1""" 2Support for the Git SCM 3""" 4 5import copy 6import glob 7import logging 8import os 9import re 10import stat 11 12import salt.utils.args 13import salt.utils.data 14import salt.utils.files 15import salt.utils.functools 16import salt.utils.itertools 17import salt.utils.path 18import salt.utils.platform 19import salt.utils.stringutils 20import salt.utils.templates 21import salt.utils.url 22from salt.exceptions import CommandExecutionError, SaltInvocationError 23from salt.utils.versions import LooseVersion as _LooseVersion 24 25log = logging.getLogger(__name__) 26 27__func_alias__ = {"rm_": "rm"} 28 29 30def __virtual__(): 31 """ 32 Only load if git exists on the system 33 """ 34 if salt.utils.path.which("git") is None: 35 return (False, "The git execution module cannot be loaded: git unavailable.") 36 else: 37 return True 38 39 40def _check_worktree_support(failhard=True): 41 """ 42 Ensure that we don't try to operate on worktrees in git < 2.5.0. 43 """ 44 git_version = version(versioninfo=False) 45 if _LooseVersion(git_version) < _LooseVersion("2.5.0"): 46 if failhard: 47 raise CommandExecutionError( 48 "Worktrees are only supported in git 2.5.0 and newer " 49 "(detected git version: {})".format(git_version) 50 ) 51 return False 52 return True 53 54 55def _config_getter( 56 get_opt, 57 key, 58 value_regex=None, 59 cwd=None, 60 user=None, 61 password=None, 62 ignore_retcode=False, 63 output_encoding=None, 64 **kwargs 65): 66 """ 67 Common code for config.get_* functions, builds and runs the git CLI command 68 and returns the result dict for the calling function to parse. 69 """ 70 kwargs = salt.utils.args.clean_kwargs(**kwargs) 71 global_ = kwargs.pop("global", False) 72 if kwargs: 73 salt.utils.args.invalid_kwargs(kwargs) 74 75 if cwd is None: 76 if not global_: 77 raise SaltInvocationError("'cwd' argument required unless global=True") 78 else: 79 cwd = _expand_path(cwd, user) 80 81 if get_opt == "--get-regexp": 82 if value_regex is not None and not isinstance(value_regex, str): 83 value_regex = str(value_regex) 84 else: 85 # Ignore value_regex 86 value_regex = None 87 88 command = ["git", "config"] 89 command.extend( 90 _which_git_config(global_, cwd, user, password, output_encoding=output_encoding) 91 ) 92 command.append(get_opt) 93 command.append(key) 94 if value_regex is not None: 95 command.append(value_regex) 96 return _git_run( 97 command, 98 cwd=cwd, 99 user=user, 100 password=password, 101 ignore_retcode=ignore_retcode, 102 failhard=False, 103 output_encoding=output_encoding, 104 ) 105 106 107def _expand_path(cwd, user): 108 """ 109 Expand home directory 110 """ 111 try: 112 to_expand = "~" + user if user else "~" 113 except TypeError: 114 # Users should never be numeric but if we don't account for this then 115 # we're going to get a traceback if someone passes this invalid input. 116 to_expand = "~" + str(user) if user else "~" 117 try: 118 return os.path.join(os.path.expanduser(to_expand), cwd) 119 except AttributeError: 120 return os.path.join(os.path.expanduser(to_expand), str(cwd)) 121 122 123def _path_is_executable_others(path): 124 """ 125 Check every part of path for executable permission 126 """ 127 prevpath = None 128 while path and path != prevpath: 129 try: 130 if not os.stat(path).st_mode & stat.S_IXOTH: 131 return False 132 except OSError: 133 return False 134 prevpath = path 135 path, _ = os.path.split(path) 136 return True 137 138 139def _format_opts(opts): 140 """ 141 Common code to inspect opts and split them if necessary 142 """ 143 if opts is None: 144 return [] 145 elif isinstance(opts, list): 146 new_opts = [] 147 for item in opts: 148 if isinstance(item, str): 149 new_opts.append(item) 150 else: 151 new_opts.append(str(item)) 152 return new_opts 153 else: 154 if not isinstance(opts, str): 155 opts = [str(opts)] 156 else: 157 opts = salt.utils.args.shlex_split(opts) 158 opts = salt.utils.data.decode(opts) 159 try: 160 if opts[-1] == "--": 161 # Strip the '--' if it was passed at the end of the opts string, 162 # it'll be added back (if necessary) in the calling function. 163 # Putting this check here keeps it from having to be repeated every 164 # time _format_opts() is invoked. 165 return opts[:-1] 166 except IndexError: 167 pass 168 return opts 169 170 171def _format_git_opts(opts): 172 """ 173 Do a version check and make sure that the installed version of git can 174 support git -c 175 """ 176 if opts: 177 version_ = version(versioninfo=False) 178 if _LooseVersion(version_) < _LooseVersion("1.7.2"): 179 raise SaltInvocationError( 180 "git_opts is only supported for git versions >= 1.7.2 " 181 "(detected: {})".format(version_) 182 ) 183 return _format_opts(opts) 184 185 186def _find_ssh_exe(): 187 """ 188 Windows only: search for Git's bundled ssh.exe in known locations 189 """ 190 # Known locations for Git's ssh.exe in Windows 191 globmasks = [ 192 os.path.join( 193 os.getenv("SystemDrive"), 194 os.sep, 195 "Program Files*", 196 "Git", 197 "usr", 198 "bin", 199 "ssh.exe", 200 ), 201 os.path.join( 202 os.getenv("SystemDrive"), os.sep, "Program Files*", "Git", "bin", "ssh.exe" 203 ), 204 ] 205 for globmask in globmasks: 206 ssh_exe = glob.glob(globmask) 207 if ssh_exe and os.path.isfile(ssh_exe[0]): 208 ret = ssh_exe[0] 209 break 210 else: 211 ret = None 212 213 return ret 214 215 216def _git_run( 217 command, 218 cwd=None, 219 user=None, 220 password=None, 221 identity=None, 222 ignore_retcode=False, 223 failhard=True, 224 redirect_stderr=False, 225 saltenv="base", 226 output_encoding=None, 227 **kwargs 228): 229 """ 230 simple, throw an exception with the error message on an error return code. 231 232 this function may be moved to the command module, spliced with 233 'cmd.run_all', and used as an alternative to 'cmd.run_all'. Some 234 commands don't return proper retcodes, so this can't replace 'cmd.run_all'. 235 """ 236 env = {} 237 238 if identity: 239 _salt_cli = __opts__.get("__cli", "") 240 errors = [] 241 missing_keys = [] 242 243 # if the statefile provides multiple identities, they need to be tried 244 # (but also allow a string instead of a list) 245 if not isinstance(identity, list): 246 # force it into a list 247 identity = [identity] 248 249 # try each of the identities, independently 250 tmp_identity_file = None 251 for id_file in identity: 252 if "salt://" in id_file: 253 with salt.utils.files.set_umask(0o077): 254 tmp_identity_file = salt.utils.files.mkstemp() 255 _id_file = id_file 256 id_file = __salt__["cp.get_file"]( 257 id_file, tmp_identity_file, saltenv 258 ) 259 if not id_file: 260 log.error("identity %s does not exist.", _id_file) 261 __salt__["file.remove"](tmp_identity_file) 262 continue 263 else: 264 if user: 265 os.chown(id_file, __salt__["file.user_to_uid"](user), -1) 266 else: 267 if not __salt__["file.file_exists"](id_file): 268 missing_keys.append(id_file) 269 log.error("identity %s does not exist.", id_file) 270 continue 271 272 env = {"GIT_IDENTITY": id_file} 273 274 # copy wrapper to area accessible by ``runas`` user 275 # currently no support in windows for wrapping git ssh 276 ssh_id_wrapper = os.path.abspath( 277 os.path.join( 278 salt.utils.templates.TEMPLATE_DIRNAME, "git/ssh-id-wrapper" 279 ) 280 ) 281 tmp_ssh_wrapper = None 282 if salt.utils.platform.is_windows(): 283 ssh_exe = _find_ssh_exe() 284 if ssh_exe is None: 285 raise CommandExecutionError( 286 "Failed to find ssh.exe, unable to use identity file" 287 ) 288 env["GIT_SSH_EXE"] = ssh_exe 289 # Use the windows batch file instead of the bourne shell script 290 ssh_id_wrapper += ".bat" 291 env["GIT_SSH"] = ssh_id_wrapper 292 elif not user or _path_is_executable_others(ssh_id_wrapper): 293 env["GIT_SSH"] = ssh_id_wrapper 294 else: 295 tmp_ssh_wrapper = salt.utils.files.mkstemp() 296 salt.utils.files.copyfile(ssh_id_wrapper, tmp_ssh_wrapper) 297 os.chmod(tmp_ssh_wrapper, 0o500) 298 os.chown(tmp_ssh_wrapper, __salt__["file.user_to_uid"](user), -1) 299 env["GIT_SSH"] = tmp_ssh_wrapper 300 301 if "salt-call" not in _salt_cli and __utils__["ssh.key_is_encrypted"]( 302 id_file 303 ): 304 errors.append( 305 "Identity file {} is passphrase-protected and cannot be " 306 "used in a non-interactive command. Using salt-call from " 307 "the minion will allow a passphrase-protected key to be " 308 "used.".format(id_file) 309 ) 310 continue 311 312 log.info("Attempting git authentication using identity file %s", id_file) 313 314 try: 315 result = __salt__["cmd.run_all"]( 316 command, 317 cwd=cwd, 318 runas=user, 319 password=password, 320 env=env, 321 python_shell=False, 322 log_callback=salt.utils.url.redact_http_basic_auth, 323 ignore_retcode=ignore_retcode, 324 redirect_stderr=redirect_stderr, 325 output_encoding=output_encoding, 326 **kwargs 327 ) 328 finally: 329 if tmp_ssh_wrapper: 330 # Cleanup the temporary ssh wrapper file 331 try: 332 __salt__["file.remove"](tmp_ssh_wrapper) 333 log.debug("Removed ssh wrapper file %s", tmp_ssh_wrapper) 334 except AttributeError: 335 # No wrapper was used 336 pass 337 except (SaltInvocationError, CommandExecutionError) as exc: 338 log.warning( 339 "Failed to remove ssh wrapper file %s: %s", 340 tmp_ssh_wrapper, 341 exc, 342 ) 343 344 if tmp_identity_file: 345 # Cleanup the temporary identity file 346 try: 347 __salt__["file.remove"](tmp_identity_file) 348 log.debug("Removed identity file %s", tmp_identity_file) 349 except AttributeError: 350 # No identify file was used 351 pass 352 except (SaltInvocationError, CommandExecutionError) as exc: 353 log.warning( 354 "Failed to remove identity file %s: %s", 355 tmp_identity_file, 356 exc, 357 ) 358 359 # If the command was successful, no need to try additional IDs 360 if result["retcode"] == 0: 361 return result 362 else: 363 err = result["stdout" if redirect_stderr else "stderr"] 364 if err: 365 errors.append(salt.utils.url.redact_http_basic_auth(err)) 366 367 # We've tried all IDs and still haven't passed, so error out 368 if failhard: 369 msg = "Unable to authenticate using identity file:\n\n{}".format( 370 "\n".join(errors) 371 ) 372 if missing_keys: 373 if errors: 374 msg += "\n\n" 375 msg += "The following identity file(s) were not found: {}".format( 376 ", ".join(missing_keys) 377 ) 378 raise CommandExecutionError(msg) 379 return result 380 381 else: 382 result = __salt__["cmd.run_all"]( 383 command, 384 cwd=cwd, 385 runas=user, 386 password=password, 387 env=env, 388 python_shell=False, 389 log_callback=salt.utils.url.redact_http_basic_auth, 390 ignore_retcode=ignore_retcode, 391 redirect_stderr=redirect_stderr, 392 output_encoding=output_encoding, 393 **kwargs 394 ) 395 396 if result["retcode"] == 0: 397 return result 398 else: 399 if failhard: 400 gitcommand = " ".join(command) if isinstance(command, list) else command 401 msg = "Command '{}' failed".format( 402 salt.utils.url.redact_http_basic_auth(gitcommand) 403 ) 404 err = result["stdout" if redirect_stderr else "stderr"] 405 if err: 406 msg += ": {}".format(salt.utils.url.redact_http_basic_auth(err)) 407 raise CommandExecutionError(msg) 408 return result 409 410 411def _get_toplevel(path, user=None, password=None, output_encoding=None): 412 """ 413 Use git rev-parse to return the top level of a repo 414 """ 415 return _git_run( 416 ["git", "rev-parse", "--show-toplevel"], 417 cwd=path, 418 user=user, 419 password=password, 420 output_encoding=output_encoding, 421 )["stdout"] 422 423 424def _git_config(cwd, user, password, output_encoding=None): 425 """ 426 Helper to retrieve git config options 427 """ 428 contextkey = "git.config." + cwd 429 if contextkey not in __context__: 430 git_dir = rev_parse( 431 cwd, 432 opts=["--git-dir"], 433 user=user, 434 password=password, 435 ignore_retcode=True, 436 output_encoding=output_encoding, 437 ) 438 if not os.path.isabs(git_dir): 439 paths = (cwd, git_dir, "config") 440 else: 441 paths = (git_dir, "config") 442 __context__[contextkey] = os.path.join(*paths) 443 return __context__[contextkey] 444 445 446def _which_git_config(global_, cwd, user, password, output_encoding=None): 447 """ 448 Based on whether global or local config is desired, return a list of CLI 449 args to include in the git config command. 450 """ 451 if global_: 452 return ["--global"] 453 version_ = _LooseVersion(version(versioninfo=False)) 454 if version_ >= _LooseVersion("1.7.10.2"): 455 # --local added in 1.7.10.2 456 return ["--local"] 457 else: 458 # For earlier versions, need to specify the path to the git config file 459 return [ 460 "--file", 461 _git_config(cwd, user, password, output_encoding=output_encoding), 462 ] 463 464 465def add( 466 cwd, 467 filename, 468 opts="", 469 git_opts="", 470 user=None, 471 password=None, 472 ignore_retcode=False, 473 output_encoding=None, 474): 475 """ 476 .. versionchanged:: 2015.8.0 477 The ``--verbose`` command line argument is now implied 478 479 Interface to `git-add(1)`_ 480 481 cwd 482 The path to the git checkout 483 484 filename 485 The location of the file/directory to add, relative to ``cwd`` 486 487 opts 488 Any additional options to add to the command line, in a single string 489 490 .. note:: 491 On the Salt CLI, if the opts are preceded with a dash, it is 492 necessary to precede them with ``opts=`` (as in the CLI examples 493 below) to avoid causing errors with Salt's own argument parsing. 494 495 git_opts 496 Any additional options to add to git command itself (not the ``add`` 497 subcommand), in a single string. This is useful for passing ``-c`` to 498 run git with temporary changes to the git configuration. 499 500 .. versionadded:: 2017.7.0 501 502 .. note:: 503 This is only supported in git 1.7.2 and newer. 504 505 user 506 User under which to run the git command. By default, the command is run 507 by the user under which the minion is running. 508 509 password 510 Windows only. Required when specifying ``user``. This parameter will be 511 ignored on non-Windows platforms. 512 513 .. versionadded:: 2016.3.4 514 515 ignore_retcode : False 516 If ``True``, do not log an error to the minion log if the git command 517 returns a nonzero exit status. 518 519 .. versionadded:: 2015.8.0 520 521 output_encoding 522 Use this option to specify which encoding to use to decode the output 523 from any git commands which are run. This should not be needed in most 524 cases. 525 526 .. note:: 527 This should only be needed if the files in the repository were 528 created with filenames using an encoding other than UTF-8 to handle 529 Unicode characters. 530 531 .. versionadded:: 2018.3.1 532 533 .. _`git-add(1)`: http://git-scm.com/docs/git-add 534 535 CLI Examples: 536 537 .. code-block:: bash 538 539 salt myminion git.add /path/to/repo foo/bar.py 540 salt myminion git.add /path/to/repo foo/bar.py opts='--dry-run' 541 """ 542 cwd = _expand_path(cwd, user) 543 command = ["git"] + _format_git_opts(git_opts) 544 command.extend(["add", "--verbose"]) 545 command.extend([x for x in _format_opts(opts) if x not in ("-v", "--verbose")]) 546 command.extend(["--", filename]) 547 return _git_run( 548 command, 549 cwd=cwd, 550 user=user, 551 password=password, 552 ignore_retcode=ignore_retcode, 553 output_encoding=output_encoding, 554 )["stdout"] 555 556 557def archive( 558 cwd, 559 output, 560 rev="HEAD", 561 prefix=None, 562 git_opts="", 563 user=None, 564 password=None, 565 ignore_retcode=False, 566 output_encoding=None, 567 **kwargs 568): 569 """ 570 .. versionchanged:: 2015.8.0 571 Returns ``True`` if successful, raises an error if not. 572 573 Interface to `git-archive(1)`_, exports a tarball/zip file of the 574 repository 575 576 cwd 577 The path to be archived 578 579 .. note:: 580 ``git archive`` permits a partial archive to be created. Thus, this 581 path does not need to be the root of the git repository. Only the 582 files within the directory specified by ``cwd`` (and its 583 subdirectories) will be in the resulting archive. For example, if 584 there is a git checkout at ``/tmp/foo``, then passing 585 ``/tmp/foo/bar`` as the ``cwd`` will result in just the files 586 underneath ``/tmp/foo/bar`` to be exported as an archive. 587 588 output 589 The path of the archive to be created 590 591 overwrite : False 592 Unless set to ``True``, Salt will over overwrite an existing archive at 593 the path specified by the ``output`` argument. 594 595 .. versionadded:: 2015.8.0 596 597 rev : HEAD 598 The revision from which to create the archive 599 600 format 601 Manually specify the file format of the resulting archive. This 602 argument can be omitted, and ``git archive`` will attempt to guess the 603 archive type (and compression) from the filename. ``zip``, ``tar``, 604 ``tar.gz``, and ``tgz`` are extensions that are recognized 605 automatically, and git can be configured to support other archive types 606 with the addition of git configuration keys. 607 608 See the `git-archive(1)`_ manpage explanation of the 609 ``--format`` argument (as well as the ``CONFIGURATION`` section of the 610 manpage) for further information. 611 612 .. versionadded:: 2015.8.0 613 614 prefix 615 Prepend ``<prefix>`` to every filename in the archive. If unspecified, 616 the name of the directory at the top level of the repository will be 617 used as the prefix (e.g. if ``cwd`` is set to ``/foo/bar/baz``, the 618 prefix will be ``baz``, and the resulting archive will contain a 619 top-level directory by that name). 620 621 .. note:: 622 The default behavior if the ``--prefix`` option for ``git archive`` 623 is not specified is to not prepend a prefix, so Salt's behavior 624 differs slightly from ``git archive`` in this respect. Use 625 ``prefix=''`` to create an archive with no prefix. 626 627 .. versionchanged:: 2015.8.0 628 The behavior of this argument has been changed slightly. As of 629 this version, it is necessary to include the trailing slash when 630 specifying a prefix, if the prefix is intended to create a 631 top-level directory. 632 633 git_opts 634 Any additional options to add to git command itself (not the 635 ``archive`` subcommand), in a single string. This is useful for passing 636 ``-c`` to run git with temporary changes to the git configuration. 637 638 .. versionadded:: 2017.7.0 639 640 .. note:: 641 This is only supported in git 1.7.2 and newer. 642 643 user 644 User under which to run the git command. By default, the command is run 645 by the user under which the minion is running. 646 647 password 648 Windows only. Required when specifying ``user``. This parameter will be 649 ignored on non-Windows platforms. 650 651 .. versionadded:: 2016.3.4 652 653 ignore_retcode : False 654 If ``True``, do not log an error to the minion log if the git command 655 returns a nonzero exit status. 656 657 .. versionadded:: 2015.8.0 658 659 output_encoding 660 Use this option to specify which encoding to use to decode the output 661 from any git commands which are run. This should not be needed in most 662 cases. 663 664 .. note:: 665 This should only be needed if the files in the repository were 666 created with filenames using an encoding other than UTF-8 to handle 667 Unicode characters. 668 669 .. versionadded:: 2018.3.1 670 671 .. _`git-archive(1)`: http://git-scm.com/docs/git-archive 672 673 CLI Example: 674 675 .. code-block:: bash 676 677 salt myminion git.archive /path/to/repo /path/to/archive.tar 678 """ 679 cwd = _expand_path(cwd, user) 680 output = _expand_path(output, user) 681 # Sanitize kwargs and make sure that no invalid ones were passed. This 682 # allows us to accept 'format' as an argument to this function without 683 # shadowing the format() global, while also not allowing unwanted arguments 684 # to be passed. 685 kwargs = salt.utils.args.clean_kwargs(**kwargs) 686 format_ = kwargs.pop("format", None) 687 if kwargs: 688 salt.utils.args.invalid_kwargs(kwargs) 689 690 command = ["git"] + _format_git_opts(git_opts) 691 command.append("archive") 692 # If prefix was set to '' then we skip adding the --prefix option, but if 693 # it was not passed (i.e. None) we use the cwd. 694 if prefix != "": 695 if not prefix: 696 prefix = os.path.basename(cwd) + os.sep 697 command.extend(["--prefix", prefix]) 698 699 if format_: 700 command.extend(["--format", format_]) 701 command.extend(["--output", output, rev]) 702 _git_run( 703 command, 704 cwd=cwd, 705 user=user, 706 password=password, 707 ignore_retcode=ignore_retcode, 708 output_encoding=output_encoding, 709 ) 710 # No output (unless --verbose is used, and we don't want all files listed 711 # in the output in case there are thousands), so just return True. If there 712 # was an error in the git command, it will have already raised an exception 713 # and we will never get to this return statement. 714 return True 715 716 717def branch( 718 cwd, 719 name=None, 720 opts="", 721 git_opts="", 722 user=None, 723 password=None, 724 ignore_retcode=False, 725 output_encoding=None, 726): 727 """ 728 Interface to `git-branch(1)`_ 729 730 cwd 731 The path to the git checkout 732 733 name 734 Name of the branch on which to operate. If not specified, the current 735 branch will be assumed. 736 737 opts 738 Any additional options to add to the command line, in a single string 739 740 .. note:: 741 To create a branch based on something other than HEAD, pass the 742 name of the revision as ``opts``. If the revision is in the format 743 ``remotename/branch``, then this will also set the remote tracking 744 branch. 745 746 Additionally, on the Salt CLI, if the opts are preceded with a 747 dash, it is necessary to precede them with ``opts=`` (as in the CLI 748 examples below) to avoid causing errors with Salt's own argument 749 parsing. 750 751 git_opts 752 Any additional options to add to git command itself (not the ``branch`` 753 subcommand), in a single string. This is useful for passing ``-c`` to 754 run git with temporary changes to the git configuration. 755 756 .. versionadded:: 2017.7.0 757 758 .. note:: 759 This is only supported in git 1.7.2 and newer. 760 761 user 762 User under which to run the git command. By default, the command is run 763 by the user under which the minion is running. 764 765 password 766 Windows only. Required when specifying ``user``. This parameter will be 767 ignored on non-Windows platforms. 768 769 .. versionadded:: 2016.3.4 770 771 ignore_retcode : False 772 If ``True``, do not log an error to the minion log if the git command 773 returns a nonzero exit status. 774 775 .. versionadded:: 2015.8.0 776 777 output_encoding 778 Use this option to specify which encoding to use to decode the output 779 from any git commands which are run. This should not be needed in most 780 cases. 781 782 .. note:: 783 This should only be needed if the files in the repository were 784 created with filenames using an encoding other than UTF-8 to handle 785 Unicode characters. 786 787 .. versionadded:: 2018.3.1 788 789 .. _`git-branch(1)`: http://git-scm.com/docs/git-branch 790 791 CLI Examples: 792 793 .. code-block:: bash 794 795 # Set remote tracking branch 796 salt myminion git.branch /path/to/repo mybranch opts='--set-upstream-to origin/mybranch' 797 # Create new branch 798 salt myminion git.branch /path/to/repo mybranch upstream/somebranch 799 # Delete branch 800 salt myminion git.branch /path/to/repo mybranch opts='-d' 801 # Rename branch (2015.8.0 and later) 802 salt myminion git.branch /path/to/repo newbranch opts='-m oldbranch' 803 """ 804 cwd = _expand_path(cwd, user) 805 command = ["git"] + _format_git_opts(git_opts) 806 command.append("branch") 807 command.extend(_format_opts(opts)) 808 if name is not None: 809 command.append(name) 810 _git_run( 811 command, 812 cwd=cwd, 813 user=user, 814 password=password, 815 ignore_retcode=ignore_retcode, 816 output_encoding=output_encoding, 817 ) 818 return True 819 820 821def checkout( 822 cwd, 823 rev=None, 824 force=False, 825 opts="", 826 git_opts="", 827 user=None, 828 password=None, 829 ignore_retcode=False, 830 output_encoding=None, 831): 832 """ 833 Interface to `git-checkout(1)`_ 834 835 cwd 836 The path to the git checkout 837 838 opts 839 Any additional options to add to the command line, in a single string 840 841 .. note:: 842 On the Salt CLI, if the opts are preceded with a dash, it is 843 necessary to precede them with ``opts=`` (as in the CLI examples 844 below) to avoid causing errors with Salt's own argument parsing. 845 846 git_opts 847 Any additional options to add to git command itself (not the 848 ``checkout`` subcommand), in a single string. This is useful for 849 passing ``-c`` to run git with temporary changes to the git 850 configuration. 851 852 .. versionadded:: 2017.7.0 853 854 .. note:: 855 This is only supported in git 1.7.2 and newer. 856 857 rev 858 The remote branch or revision to checkout. 859 860 .. versionchanged:: 2015.8.0 861 Optional when using ``-b`` or ``-B`` in ``opts``. 862 863 force : False 864 Force a checkout even if there might be overwritten changes 865 866 user 867 User under which to run the git command. By default, the command is run 868 by the user under which the minion is running. 869 870 password 871 Windows only. Required when specifying ``user``. This parameter will be 872 ignored on non-Windows platforms. 873 874 .. versionadded:: 2016.3.4 875 876 ignore_retcode : False 877 If ``True``, do not log an error to the minion log if the git command 878 returns a nonzero exit status. 879 880 .. versionadded:: 2015.8.0 881 882 output_encoding 883 Use this option to specify which encoding to use to decode the output 884 from any git commands which are run. This should not be needed in most 885 cases. 886 887 .. note:: 888 This should only be needed if the files in the repository were 889 created with filenames using an encoding other than UTF-8 to handle 890 Unicode characters. 891 892 .. versionadded:: 2018.3.1 893 894 .. _`git-checkout(1)`: http://git-scm.com/docs/git-checkout 895 896 CLI Examples: 897 898 .. code-block:: bash 899 900 # Checking out local local revisions 901 salt myminion git.checkout /path/to/repo somebranch user=jeff 902 salt myminion git.checkout /path/to/repo opts='testbranch -- conf/file1 file2' 903 salt myminion git.checkout /path/to/repo rev=origin/mybranch opts='--track' 904 # Checking out remote revision into new branch 905 salt myminion git.checkout /path/to/repo upstream/master opts='-b newbranch' 906 # Checking out current revision into new branch (2015.8.0 and later) 907 salt myminion git.checkout /path/to/repo opts='-b newbranch' 908 """ 909 cwd = _expand_path(cwd, user) 910 command = ["git"] + _format_git_opts(git_opts) 911 command.append("checkout") 912 if force: 913 command.append("--force") 914 opts = _format_opts(opts) 915 command.extend(opts) 916 checkout_branch = any(x in opts for x in ("-b", "-B")) 917 if rev is None: 918 if not checkout_branch: 919 raise SaltInvocationError( 920 "'rev' argument is required unless -b or -B in opts" 921 ) 922 else: 923 command.append(rev) 924 # Checkout message goes to stderr 925 return _git_run( 926 command, 927 cwd=cwd, 928 user=user, 929 password=password, 930 ignore_retcode=ignore_retcode, 931 redirect_stderr=True, 932 output_encoding=output_encoding, 933 )["stdout"] 934 935 936def clone( 937 cwd, 938 url=None, # Remove default value once 'repository' arg is removed 939 name=None, 940 opts="", 941 git_opts="", 942 user=None, 943 password=None, 944 identity=None, 945 https_user=None, 946 https_pass=None, 947 ignore_retcode=False, 948 saltenv="base", 949 output_encoding=None, 950): 951 """ 952 Interface to `git-clone(1)`_ 953 954 cwd 955 Location of git clone 956 957 .. versionchanged:: 2015.8.0 958 If ``name`` is passed, then the clone will be made *within* this 959 directory. 960 961 url 962 The URL of the repository to be cloned 963 964 .. versionchanged:: 2015.8.0 965 Argument renamed from ``repository`` to ``url`` 966 967 name 968 Optional alternate name for the top-level directory to be created by 969 the clone 970 971 .. versionadded:: 2015.8.0 972 973 opts 974 Any additional options to add to the command line, in a single string 975 976 git_opts 977 Any additional options to add to git command itself (not the ``clone`` 978 subcommand), in a single string. This is useful for passing ``-c`` to 979 run git with temporary changes to the git configuration. 980 981 .. versionadded:: 2017.7.0 982 983 .. note:: 984 This is only supported in git 1.7.2 and newer. 985 986 user 987 User under which to run the git command. By default, the command is run 988 by the user under which the minion is running. 989 990 password 991 Windows only. Required when specifying ``user``. This parameter will be 992 ignored on non-Windows platforms. 993 994 .. versionadded:: 2016.3.4 995 996 identity 997 Path to a private key to use for ssh URLs 998 999 .. warning:: 1000 1001 Unless Salt is invoked from the minion using ``salt-call``, the 1002 key(s) must be passphraseless. For greater security with 1003 passphraseless private keys, see the `sshd(8)`_ manpage for 1004 information on securing the keypair from the remote side in the 1005 ``authorized_keys`` file. 1006 1007 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 1008 1009 .. versionchanged:: 2015.8.7 1010 1011 Salt will no longer attempt to use passphrase-protected keys unless 1012 invoked from the minion using ``salt-call``, to prevent blocking 1013 waiting for user input. 1014 1015 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 1016 1017 .. versionchanged:: 2016.3.0 1018 1019 https_user 1020 Set HTTP Basic Auth username. Only accepted for HTTPS URLs. 1021 1022 .. versionadded:: 20515.5.0 1023 1024 https_pass 1025 Set HTTP Basic Auth password. Only accepted for HTTPS URLs. 1026 1027 .. versionadded:: 2015.5.0 1028 1029 ignore_retcode : False 1030 If ``True``, do not log an error to the minion log if the git command 1031 returns a nonzero exit status. 1032 1033 .. versionadded:: 2015.8.0 1034 1035 saltenv 1036 The default salt environment to pull sls files from 1037 1038 .. versionadded:: 2016.3.1 1039 1040 output_encoding 1041 Use this option to specify which encoding to use to decode the output 1042 from any git commands which are run. This should not be needed in most 1043 cases. 1044 1045 .. note:: 1046 This should only be needed if the files in the repository were 1047 created with filenames using an encoding other than UTF-8 to handle 1048 Unicode characters. 1049 1050 .. versionadded:: 2018.3.1 1051 1052 .. _`git-clone(1)`: http://git-scm.com/docs/git-clone 1053 1054 CLI Example: 1055 1056 .. code-block:: bash 1057 1058 salt myminion git.clone /path/to/repo_parent_dir git://github.com/saltstack/salt.git 1059 """ 1060 cwd = _expand_path(cwd, user) 1061 1062 if not url: 1063 raise SaltInvocationError("Missing 'url' argument") 1064 1065 try: 1066 url = salt.utils.url.add_http_basic_auth( 1067 url, https_user, https_pass, https_only=True 1068 ) 1069 except ValueError as exc: 1070 raise SaltInvocationError(exc.__str__()) 1071 1072 command = ["git"] + _format_git_opts(git_opts) 1073 command.append("clone") 1074 command.extend(_format_opts(opts)) 1075 command.extend(["--", url]) 1076 if name is not None: 1077 command.append(name) 1078 if not os.path.exists(cwd): 1079 os.makedirs(cwd) 1080 clone_cwd = cwd 1081 else: 1082 command.append(cwd) 1083 # Use '/tmp' instead of $HOME (/root for root user) to work around 1084 # upstream git bug. See the following comment on the Salt bug tracker 1085 # for more info: 1086 # https://github.com/saltstack/salt/issues/15519#issuecomment-128531310 1087 # On Windows, just fall back to None (runs git clone command using the 1088 # home directory as the cwd). 1089 clone_cwd = "/tmp" if not salt.utils.platform.is_windows() else None 1090 _git_run( 1091 command, 1092 cwd=clone_cwd, 1093 user=user, 1094 password=password, 1095 identity=identity, 1096 ignore_retcode=ignore_retcode, 1097 saltenv=saltenv, 1098 output_encoding=output_encoding, 1099 ) 1100 return True 1101 1102 1103def commit( 1104 cwd, 1105 message, 1106 opts="", 1107 git_opts="", 1108 user=None, 1109 password=None, 1110 filename=None, 1111 ignore_retcode=False, 1112 output_encoding=None, 1113): 1114 """ 1115 Interface to `git-commit(1)`_ 1116 1117 cwd 1118 The path to the git checkout 1119 1120 message 1121 Commit message 1122 1123 opts 1124 Any additional options to add to the command line, in a single string. 1125 These opts will be added to the end of the git command being run. 1126 1127 .. note:: 1128 On the Salt CLI, if the opts are preceded with a dash, it is 1129 necessary to precede them with ``opts=`` (as in the CLI examples 1130 below) to avoid causing errors with Salt's own argument parsing. 1131 1132 The ``-m`` option should not be passed here, as the commit message 1133 will be defined by the ``message`` argument. 1134 1135 git_opts 1136 Any additional options to add to git command itself (not the ``commit`` 1137 subcommand), in a single string. This is useful for passing ``-c`` to 1138 run git with temporary changes to the git configuration. 1139 1140 .. versionadded:: 2017.7.0 1141 1142 .. note:: 1143 This is only supported in git 1.7.2 and newer. 1144 1145 user 1146 User under which to run the git command. By default, the command is run 1147 by the user under which the minion is running. 1148 1149 password 1150 Windows only. Required when specifying ``user``. This parameter will be 1151 ignored on non-Windows platforms. 1152 1153 .. versionadded:: 2016.3.4 1154 1155 filename 1156 The location of the file/directory to commit, relative to ``cwd``. 1157 This argument is optional, and can be used to commit a file without 1158 first staging it. 1159 1160 .. note:: 1161 This argument only works on files which are already tracked by the 1162 git repository. 1163 1164 .. versionadded:: 2015.8.0 1165 1166 ignore_retcode : False 1167 If ``True``, do not log an error to the minion log if the git command 1168 returns a nonzero exit status. 1169 1170 .. versionadded:: 2015.8.0 1171 1172 output_encoding 1173 Use this option to specify which encoding to use to decode the output 1174 from any git commands which are run. This should not be needed in most 1175 cases. 1176 1177 .. note:: 1178 This should only be needed if the files in the repository were 1179 created with filenames using an encoding other than UTF-8 to handle 1180 Unicode characters. 1181 1182 .. versionadded:: 2018.3.1 1183 1184 .. _`git-commit(1)`: http://git-scm.com/docs/git-commit 1185 1186 CLI Examples: 1187 1188 .. code-block:: bash 1189 1190 salt myminion git.commit /path/to/repo 'The commit message' 1191 salt myminion git.commit /path/to/repo 'The commit message' filename=foo/bar.py 1192 """ 1193 cwd = _expand_path(cwd, user) 1194 command = ["git"] + _format_git_opts(git_opts) 1195 command.extend(["commit", "-m", message]) 1196 command.extend(_format_opts(opts)) 1197 if filename: 1198 # Add the '--' to terminate CLI args, but only if it wasn't already 1199 # passed in opts string. 1200 command.extend(["--", filename]) 1201 return _git_run( 1202 command, 1203 cwd=cwd, 1204 user=user, 1205 password=password, 1206 ignore_retcode=ignore_retcode, 1207 output_encoding=output_encoding, 1208 )["stdout"] 1209 1210 1211def config_get( 1212 key, 1213 cwd=None, 1214 user=None, 1215 password=None, 1216 ignore_retcode=False, 1217 output_encoding=None, 1218 **kwargs 1219): 1220 """ 1221 Get the value of a key in the git configuration file 1222 1223 key 1224 The name of the configuration key to get 1225 1226 .. versionchanged:: 2015.8.0 1227 Argument renamed from ``setting_name`` to ``key`` 1228 1229 cwd 1230 The path to the git checkout 1231 1232 .. versionchanged:: 2015.8.0 1233 Now optional if ``global`` is set to ``True`` 1234 1235 global : False 1236 If ``True``, query the global git configuration. Otherwise, only the 1237 local git configuration will be queried. 1238 1239 .. versionadded:: 2015.8.0 1240 1241 all : False 1242 If ``True``, return a list of all values set for ``key``. If the key 1243 does not exist, ``None`` will be returned. 1244 1245 .. versionadded:: 2015.8.0 1246 1247 user 1248 User under which to run the git command. By default, the command is run 1249 by the user under which the minion is running. 1250 1251 password 1252 Windows only. Required when specifying ``user``. This parameter will be 1253 ignored on non-Windows platforms. 1254 1255 .. versionadded:: 2016.3.4 1256 1257 ignore_retcode : False 1258 If ``True``, do not log an error to the minion log if the git command 1259 returns a nonzero exit status. 1260 1261 .. versionadded:: 2015.8.0 1262 1263 output_encoding 1264 Use this option to specify which encoding to use to decode the output 1265 from any git commands which are run. This should not be needed in most 1266 cases. 1267 1268 .. note:: 1269 This should only be needed if the files in the repository were 1270 created with filenames using an encoding other than UTF-8 to handle 1271 Unicode characters. 1272 1273 .. versionadded:: 2018.3.1 1274 1275 CLI Examples: 1276 1277 .. code-block:: bash 1278 1279 salt myminion git.config_get user.name cwd=/path/to/repo 1280 salt myminion git.config_get user.email global=True 1281 salt myminion git.config_get core.gitproxy cwd=/path/to/repo all=True 1282 """ 1283 # Sanitize kwargs and make sure that no invalid ones were passed. This 1284 # allows us to accept 'all' as an argument to this function without 1285 # shadowing all(), while also not allowing unwanted arguments to be passed. 1286 all_ = kwargs.pop("all", False) 1287 1288 result = _config_getter( 1289 "--get-all", 1290 key, 1291 cwd=cwd, 1292 user=user, 1293 password=password, 1294 ignore_retcode=ignore_retcode, 1295 output_encoding=output_encoding, 1296 **kwargs 1297 ) 1298 1299 # git config --get exits with retcode of 1 when key does not exist 1300 if result["retcode"] == 1: 1301 return None 1302 ret = result["stdout"].splitlines() 1303 if all_: 1304 return ret 1305 else: 1306 try: 1307 return ret[-1] 1308 except IndexError: 1309 # Should never happen but I'm paranoid and don't like tracebacks 1310 return "" 1311 1312 1313def config_get_regexp( 1314 key, 1315 value_regex=None, 1316 cwd=None, 1317 user=None, 1318 password=None, 1319 ignore_retcode=False, 1320 output_encoding=None, 1321 **kwargs 1322): 1323 r""" 1324 .. versionadded:: 2015.8.0 1325 1326 Get the value of a key or keys in the git configuration file using regexes 1327 for more flexible matching. The return data is a dictionary mapping keys to 1328 lists of values matching the ``value_regex``. If no values match, an empty 1329 dictionary will be returned. 1330 1331 key 1332 Regex on which key names will be matched 1333 1334 value_regex 1335 If specified, return all values matching this regex. The return data 1336 will be a dictionary mapping keys to lists of values matching the 1337 regex. 1338 1339 .. important:: 1340 Only values matching the ``value_regex`` will be part of the return 1341 data. So, if ``key`` matches a multivar, then it is possible that 1342 not all of the values will be returned. To get all values set for a 1343 multivar, simply omit the ``value_regex`` argument. 1344 1345 cwd 1346 The path to the git checkout 1347 1348 global : False 1349 If ``True``, query the global git configuration. Otherwise, only the 1350 local git configuration will be queried. 1351 1352 user 1353 User under which to run the git command. By default, the command is run 1354 by the user under which the minion is running. 1355 1356 password 1357 Windows only. Required when specifying ``user``. This parameter will be 1358 ignored on non-Windows platforms. 1359 1360 .. versionadded:: 2016.3.4 1361 1362 ignore_retcode : False 1363 If ``True``, do not log an error to the minion log if the git command 1364 returns a nonzero exit status. 1365 1366 output_encoding 1367 Use this option to specify which encoding to use to decode the output 1368 from any git commands which are run. This should not be needed in most 1369 cases. 1370 1371 .. note:: 1372 This should only be needed if the files in the repository were 1373 created with filenames using an encoding other than UTF-8 to handle 1374 Unicode characters. 1375 1376 .. versionadded:: 2018.3.1 1377 1378 CLI Examples: 1379 1380 .. code-block:: bash 1381 1382 # Matches any values for key 'foo.bar' 1383 salt myminion git.config_get_regexp /path/to/repo foo.bar 1384 # Matches any value starting with 'baz' set for key 'foo.bar' 1385 salt myminion git.config_get_regexp /path/to/repo foo.bar 'baz.*' 1386 # Matches any key starting with 'user.' 1387 salt myminion git.config_get_regexp '^user\.' global=True 1388 """ 1389 result = _config_getter( 1390 "--get-regexp", 1391 key, 1392 value_regex=value_regex, 1393 cwd=cwd, 1394 user=user, 1395 password=password, 1396 ignore_retcode=ignore_retcode, 1397 output_encoding=output_encoding, 1398 **kwargs 1399 ) 1400 1401 # git config --get exits with retcode of 1 when key does not exist 1402 ret = {} 1403 if result["retcode"] == 1: 1404 return ret 1405 for line in result["stdout"].splitlines(): 1406 try: 1407 param, value = line.split(None, 1) 1408 except ValueError: 1409 continue 1410 ret.setdefault(param, []).append(value) 1411 return ret 1412 1413 1414config_get_regex = salt.utils.functools.alias_function( 1415 config_get_regexp, "config_get_regex" 1416) 1417 1418 1419def config_set( 1420 key, 1421 value=None, 1422 multivar=None, 1423 cwd=None, 1424 user=None, 1425 password=None, 1426 ignore_retcode=False, 1427 output_encoding=None, 1428 **kwargs 1429): 1430 """ 1431 .. versionchanged:: 2015.8.0 1432 Return the value(s) of the key being set 1433 1434 Set a key in the git configuration file 1435 1436 cwd 1437 The path to the git checkout. Must be an absolute path, or the word 1438 ``global`` to indicate that a global key should be set. 1439 1440 .. versionchanged:: 2014.7.0 1441 Made ``cwd`` argument optional if ``is_global=True`` 1442 1443 key 1444 The name of the configuration key to set 1445 1446 .. versionchanged:: 2015.8.0 1447 Argument renamed from ``setting_name`` to ``key`` 1448 1449 value 1450 The value to set for the specified key. Incompatible with the 1451 ``multivar`` argument. 1452 1453 .. versionchanged:: 2015.8.0 1454 Argument renamed from ``setting_value`` to ``value`` 1455 1456 add : False 1457 Add a value to a key, creating/updating a multivar 1458 1459 .. versionadded:: 2015.8.0 1460 1461 multivar 1462 Set a multivar all at once. Values can be comma-separated or passed as 1463 a Python list. Incompatible with the ``value`` argument. 1464 1465 .. versionadded:: 2015.8.0 1466 1467 user 1468 User under which to run the git command. By default, the command is run 1469 by the user under which the minion is running. 1470 1471 password 1472 Windows only. Required when specifying ``user``. This parameter will be 1473 ignored on non-Windows platforms. 1474 1475 .. versionadded:: 2016.3.4 1476 1477 ignore_retcode : False 1478 If ``True``, do not log an error to the minion log if the git command 1479 returns a nonzero exit status. 1480 1481 .. versionadded:: 2015.8.0 1482 1483 global : False 1484 If ``True``, set a global variable 1485 1486 output_encoding 1487 Use this option to specify which encoding to use to decode the output 1488 from any git commands which are run. This should not be needed in most 1489 cases. 1490 1491 .. note:: 1492 This should only be needed if the files in the repository were 1493 created with filenames using an encoding other than UTF-8 to handle 1494 Unicode characters. 1495 1496 .. versionadded:: 2018.3.1 1497 1498 CLI Examples: 1499 1500 .. code-block:: bash 1501 1502 salt myminion git.config_set user.email me@example.com cwd=/path/to/repo 1503 salt myminion git.config_set user.email foo@bar.com global=True 1504 """ 1505 kwargs = salt.utils.args.clean_kwargs(**kwargs) 1506 add_ = kwargs.pop("add", False) 1507 global_ = kwargs.pop("global", False) 1508 if kwargs: 1509 salt.utils.args.invalid_kwargs(kwargs) 1510 1511 if cwd is None: 1512 if not global_: 1513 raise SaltInvocationError("'cwd' argument required unless global=True") 1514 else: 1515 cwd = _expand_path(cwd, user) 1516 1517 if all(x is not None for x in (value, multivar)): 1518 raise SaltInvocationError("Only one of 'value' and 'multivar' is permitted") 1519 1520 if multivar is not None: 1521 if not isinstance(multivar, list): 1522 try: 1523 multivar = multivar.split(",") 1524 except AttributeError: 1525 multivar = str(multivar).split(",") 1526 else: 1527 new_multivar = [] 1528 for item in salt.utils.data.decode(multivar): 1529 if isinstance(item, str): 1530 new_multivar.append(item) 1531 else: 1532 new_multivar.append(str(item)) 1533 multivar = new_multivar 1534 1535 command_prefix = ["git", "config"] 1536 if global_: 1537 command_prefix.append("--global") 1538 1539 if value is not None: 1540 command = copy.copy(command_prefix) 1541 if add_: 1542 command.append("--add") 1543 else: 1544 command.append("--replace-all") 1545 command.extend([key, value]) 1546 _git_run( 1547 command, 1548 cwd=cwd, 1549 user=user, 1550 password=password, 1551 ignore_retcode=ignore_retcode, 1552 output_encoding=output_encoding, 1553 ) 1554 else: 1555 for idx, target in enumerate(multivar): 1556 command = copy.copy(command_prefix) 1557 if idx == 0: 1558 command.append("--replace-all") 1559 else: 1560 command.append("--add") 1561 command.extend([key, target]) 1562 _git_run( 1563 command, 1564 cwd=cwd, 1565 user=user, 1566 password=password, 1567 ignore_retcode=ignore_retcode, 1568 output_encoding=output_encoding, 1569 ) 1570 return config_get( 1571 key, 1572 user=user, 1573 password=password, 1574 cwd=cwd, 1575 ignore_retcode=ignore_retcode, 1576 output_encoding=output_encoding, 1577 **{"all": True, "global": global_} 1578 ) 1579 1580 1581def config_unset( 1582 key, 1583 value_regex=None, 1584 cwd=None, 1585 user=None, 1586 password=None, 1587 ignore_retcode=False, 1588 output_encoding=None, 1589 **kwargs 1590): 1591 """ 1592 .. versionadded:: 2015.8.0 1593 1594 Unset a key in the git configuration file 1595 1596 cwd 1597 The path to the git checkout. Must be an absolute path, or the word 1598 ``global`` to indicate that a global key should be unset. 1599 1600 key 1601 The name of the configuration key to unset 1602 1603 value_regex 1604 Regular expression that matches exactly one key, used to delete a 1605 single value from a multivar. Ignored if ``all`` is set to ``True``. 1606 1607 all : False 1608 If ``True`` unset all values for a multivar. If ``False``, and ``key`` 1609 is a multivar, an error will be raised. 1610 1611 global : False 1612 If ``True``, unset set a global variable. Otherwise, a local variable 1613 will be unset. 1614 1615 user 1616 User under which to run the git command. By default, the command is run 1617 by the user under which the minion is running. 1618 1619 password 1620 Windows only. Required when specifying ``user``. This parameter will be 1621 ignored on non-Windows platforms. 1622 1623 .. versionadded:: 2016.3.4 1624 1625 ignore_retcode : False 1626 If ``True``, do not log an error to the minion log if the git command 1627 returns a nonzero exit status. 1628 1629 output_encoding 1630 Use this option to specify which encoding to use to decode the output 1631 from any git commands which are run. This should not be needed in most 1632 cases. 1633 1634 .. note:: 1635 This should only be needed if the files in the repository were 1636 created with filenames using an encoding other than UTF-8 to handle 1637 Unicode characters. 1638 1639 .. versionadded:: 2018.3.1 1640 1641 CLI Example: 1642 1643 .. code-block:: bash 1644 1645 salt myminion git.config_unset /path/to/repo foo.bar 1646 salt myminion git.config_unset /path/to/repo foo.bar all=True 1647 """ 1648 kwargs = salt.utils.args.clean_kwargs(**kwargs) 1649 all_ = kwargs.pop("all", False) 1650 global_ = kwargs.pop("global", False) 1651 if kwargs: 1652 salt.utils.args.invalid_kwargs(kwargs) 1653 1654 if cwd is None: 1655 if not global_: 1656 raise SaltInvocationError("'cwd' argument required unless global=True") 1657 else: 1658 cwd = _expand_path(cwd, user) 1659 1660 command = ["git", "config"] 1661 if all_: 1662 command.append("--unset-all") 1663 else: 1664 command.append("--unset") 1665 command.extend( 1666 _which_git_config(global_, cwd, user, password, output_encoding=output_encoding) 1667 ) 1668 1669 command.append(key) 1670 if value_regex is not None: 1671 command.append(value_regex) 1672 ret = _git_run( 1673 command, 1674 cwd=cwd if cwd != "global" else None, 1675 user=user, 1676 password=password, 1677 ignore_retcode=ignore_retcode, 1678 failhard=False, 1679 output_encoding=output_encoding, 1680 ) 1681 retcode = ret["retcode"] 1682 if retcode == 0: 1683 return True 1684 elif retcode == 1: 1685 raise CommandExecutionError("Section or key is invalid") 1686 elif retcode == 5: 1687 if ( 1688 config_get( 1689 key, 1690 cwd=cwd, 1691 user=user, 1692 password=password, 1693 ignore_retcode=ignore_retcode, 1694 output_encoding=output_encoding, 1695 ) 1696 is None 1697 ): 1698 raise CommandExecutionError("Key '{}' does not exist".format(key)) 1699 else: 1700 msg = "Multiple values exist for key '{}'".format(key) 1701 if value_regex is not None: 1702 msg += " and value_regex matches multiple values" 1703 raise CommandExecutionError(msg) 1704 elif retcode == 6: 1705 raise CommandExecutionError("The value_regex is invalid") 1706 else: 1707 msg = "Failed to unset key '{}', git config returned exit code {}".format( 1708 key, retcode 1709 ) 1710 if ret["stderr"]: 1711 msg += "; " + ret["stderr"] 1712 raise CommandExecutionError(msg) 1713 1714 1715def current_branch( 1716 cwd, user=None, password=None, ignore_retcode=False, output_encoding=None 1717): 1718 """ 1719 Returns the current branch name of a local checkout. If HEAD is detached, 1720 return the SHA1 of the revision which is currently checked out. 1721 1722 cwd 1723 The path to the git checkout 1724 1725 user 1726 User under which to run the git command. By default, the command is run 1727 by the user under which the minion is running. 1728 1729 password 1730 Windows only. Required when specifying ``user``. This parameter will be 1731 ignored on non-Windows platforms. 1732 1733 .. versionadded:: 2016.3.4 1734 1735 ignore_retcode : False 1736 If ``True``, do not log an error to the minion log if the git command 1737 returns a nonzero exit status. 1738 1739 .. versionadded:: 2015.8.0 1740 1741 output_encoding 1742 Use this option to specify which encoding to use to decode the output 1743 from any git commands which are run. This should not be needed in most 1744 cases. 1745 1746 .. note:: 1747 This should only be needed if the files in the repository were 1748 created with filenames using an encoding other than UTF-8 to handle 1749 Unicode characters. 1750 1751 .. versionadded:: 2018.3.1 1752 1753 CLI Example: 1754 1755 .. code-block:: bash 1756 1757 salt myminion git.current_branch /path/to/repo 1758 """ 1759 cwd = _expand_path(cwd, user) 1760 command = ["git", "rev-parse", "--abbrev-ref", "HEAD"] 1761 return _git_run( 1762 command, 1763 cwd=cwd, 1764 user=user, 1765 password=password, 1766 ignore_retcode=ignore_retcode, 1767 output_encoding=output_encoding, 1768 )["stdout"] 1769 1770 1771def describe( 1772 cwd, 1773 rev="HEAD", 1774 user=None, 1775 password=None, 1776 ignore_retcode=False, 1777 output_encoding=None, 1778): 1779 """ 1780 Returns the `git-describe(1)`_ string (or the SHA1 hash if there are no 1781 tags) for the given revision. 1782 1783 cwd 1784 The path to the git checkout 1785 1786 rev : HEAD 1787 The revision to describe 1788 1789 user 1790 User under which to run the git command. By default, the command is run 1791 by the user under which the minion is running. 1792 1793 password 1794 Windows only. Required when specifying ``user``. This parameter will be 1795 ignored on non-Windows platforms. 1796 1797 .. versionadded:: 2016.3.4 1798 1799 ignore_retcode : False 1800 If ``True``, do not log an error to the minion log if the git command 1801 returns a nonzero exit status. 1802 1803 .. versionadded:: 2015.8.0 1804 1805 output_encoding 1806 Use this option to specify which encoding to use to decode the output 1807 from any git commands which are run. This should not be needed in most 1808 cases. 1809 1810 .. note:: 1811 This should only be needed if the files in the repository were 1812 created with filenames using an encoding other than UTF-8 to handle 1813 Unicode characters. 1814 1815 .. versionadded:: 2018.3.1 1816 1817 .. _`git-describe(1)`: http://git-scm.com/docs/git-describe 1818 1819 CLI Examples: 1820 1821 .. code-block:: bash 1822 1823 salt myminion git.describe /path/to/repo 1824 salt myminion git.describe /path/to/repo develop 1825 """ 1826 cwd = _expand_path(cwd, user) 1827 command = ["git", "describe"] 1828 if _LooseVersion(version(versioninfo=False)) >= _LooseVersion("1.5.6"): 1829 command.append("--always") 1830 command.append(rev) 1831 return _git_run( 1832 command, 1833 cwd=cwd, 1834 user=user, 1835 password=password, 1836 ignore_retcode=ignore_retcode, 1837 output_encoding=output_encoding, 1838 )["stdout"] 1839 1840 1841def diff( 1842 cwd, 1843 item1=None, 1844 item2=None, 1845 opts="", 1846 git_opts="", 1847 user=None, 1848 password=None, 1849 no_index=False, 1850 cached=False, 1851 paths=None, 1852 output_encoding=None, 1853): 1854 """ 1855 .. versionadded:: 2015.8.12,2016.3.3,2016.11.0 1856 1857 Interface to `git-diff(1)`_ 1858 1859 cwd 1860 The path to the git checkout 1861 1862 item1 and item2 1863 Revision(s) to pass to the ``git diff`` command. One or both of these 1864 arguments may be ignored if some of the options below are set to 1865 ``True``. When ``cached`` is ``False``, and no revisions are passed 1866 to this function, then the current working tree will be compared 1867 against the index (i.e. unstaged changes). When two revisions are 1868 passed, they will be compared to each other. 1869 1870 opts 1871 Any additional options to add to the command line, in a single string 1872 1873 .. note:: 1874 On the Salt CLI, if the opts are preceded with a dash, it is 1875 necessary to precede them with ``opts=`` (as in the CLI examples 1876 below) to avoid causing errors with Salt's own argument parsing. 1877 1878 git_opts 1879 Any additional options to add to git command itself (not the ``diff`` 1880 subcommand), in a single string. This is useful for passing ``-c`` to 1881 run git with temporary changes to the git configuration. 1882 1883 .. versionadded:: 2017.7.0 1884 1885 .. note:: 1886 This is only supported in git 1.7.2 and newer. 1887 1888 user 1889 User under which to run the git command. By default, the command is run 1890 by the user under which the minion is running. 1891 1892 password 1893 Windows only. Required when specifying ``user``. This parameter will be 1894 ignored on non-Windows platforms. 1895 1896 .. versionadded:: 2016.3.4 1897 1898 no_index : False 1899 When it is necessary to diff two files in the same repo against each 1900 other, and not diff two different revisions, set this option to 1901 ``True``. If this is left ``False`` in these instances, then a normal 1902 ``git diff`` will be performed against the index (i.e. unstaged 1903 changes), and files in the ``paths`` option will be used to narrow down 1904 the diff output. 1905 1906 .. note:: 1907 Requires Git 1.5.1 or newer. Additionally, when set to ``True``, 1908 ``item1`` and ``item2`` will be ignored. 1909 1910 cached : False 1911 If ``True``, compare staged changes to ``item1`` (if specified), 1912 otherwise compare them to the most recent commit. 1913 1914 .. note:: 1915 ``item2`` is ignored if this option is is set to ``True``. 1916 1917 paths 1918 File paths to pass to the ``git diff`` command. Can be passed as a 1919 comma-separated list or a Python list. 1920 1921 output_encoding 1922 Use this option to specify which encoding to use to decode the output 1923 from any git commands which are run. This should not be needed in most 1924 cases. 1925 1926 .. note:: 1927 This should only be needed if the files in the repository were 1928 created with filenames using an encoding other than UTF-8 to handle 1929 Unicode characters. 1930 1931 .. versionadded:: 2018.3.1 1932 1933 .. _`git-diff(1)`: http://git-scm.com/docs/git-diff 1934 1935 CLI Example: 1936 1937 .. code-block:: bash 1938 1939 # Perform diff against the index (staging area for next commit) 1940 salt myminion git.diff /path/to/repo 1941 # Compare staged changes to the most recent commit 1942 salt myminion git.diff /path/to/repo cached=True 1943 # Compare staged changes to a specific revision 1944 salt myminion git.diff /path/to/repo mybranch cached=True 1945 # Perform diff against the most recent commit (includes staged changes) 1946 salt myminion git.diff /path/to/repo HEAD 1947 # Diff two commits 1948 salt myminion git.diff /path/to/repo abcdef1 aabbccd 1949 # Diff two commits, only showing differences in the specified paths 1950 salt myminion git.diff /path/to/repo abcdef1 aabbccd paths=path/to/file1,path/to/file2 1951 # Diff two files with one being outside the working tree 1952 salt myminion git.diff /path/to/repo no_index=True paths=path/to/file1,/absolute/path/to/file2 1953 """ 1954 if no_index and cached: 1955 raise CommandExecutionError( 1956 "The 'no_index' and 'cached' options cannot be used together" 1957 ) 1958 1959 command = ["git"] + _format_git_opts(git_opts) 1960 command.append("diff") 1961 command.extend(_format_opts(opts)) 1962 1963 if paths is not None and not isinstance(paths, (list, tuple)): 1964 try: 1965 paths = paths.split(",") 1966 except AttributeError: 1967 paths = str(paths).split(",") 1968 1969 ignore_retcode = False 1970 failhard = True 1971 1972 if no_index: 1973 if _LooseVersion(version(versioninfo=False)) < _LooseVersion("1.5.1"): 1974 raise CommandExecutionError( 1975 "The 'no_index' option is only supported in Git 1.5.1 and newer" 1976 ) 1977 ignore_retcode = True 1978 failhard = False 1979 command.append("--no-index") 1980 for value in [x for x in (item1, item2) if x]: 1981 log.warning( 1982 "Revision '%s' ignored in git diff, as revisions cannot be " 1983 "used when no_index=True", 1984 value, 1985 ) 1986 1987 elif cached: 1988 command.append("--cached") 1989 if item1: 1990 command.append(item1) 1991 if item2: 1992 log.warning( 1993 "Second revision '%s' ignored in git diff, at most one " 1994 "revision is considered when cached=True", 1995 item2, 1996 ) 1997 1998 else: 1999 for value in [x for x in (item1, item2) if x]: 2000 command.append(value) 2001 2002 if paths: 2003 command.append("--") 2004 command.extend(paths) 2005 2006 return _git_run( 2007 command, 2008 cwd=cwd, 2009 user=user, 2010 password=password, 2011 ignore_retcode=ignore_retcode, 2012 failhard=failhard, 2013 redirect_stderr=True, 2014 output_encoding=output_encoding, 2015 )["stdout"] 2016 2017 2018def discard_local_changes( 2019 cwd, path=".", user=None, password=None, ignore_retcode=False, output_encoding=None 2020): 2021 """ 2022 .. versionadded:: 2019.2.0 2023 2024 Runs a ``git checkout -- <path>`` from the directory specified by ``cwd``. 2025 2026 cwd 2027 The path to the git checkout 2028 2029 path 2030 path relative to cwd (defaults to ``.``) 2031 2032 user 2033 User under which to run the git command. By default, the command is run 2034 by the user under which the minion is running. 2035 2036 password 2037 Windows only. Required when specifying ``user``. This parameter will be 2038 ignored on non-Windows platforms. 2039 2040 ignore_retcode : False 2041 If ``True``, do not log an error to the minion log if the git command 2042 returns a nonzero exit status. 2043 2044 output_encoding 2045 Use this option to specify which encoding to use to decode the output 2046 from any git commands which are run. This should not be needed in most 2047 cases. 2048 2049 .. note:: 2050 This should only be needed if the files in the repository were 2051 created with filenames using an encoding other than UTF-8 to handle 2052 Unicode characters. 2053 2054 CLI Example: 2055 2056 .. code-block:: bash 2057 2058 salt myminion git.discard_local_changes /path/to/repo 2059 salt myminion git.discard_local_changes /path/to/repo path=foo 2060 """ 2061 cwd = _expand_path(cwd, user) 2062 command = ["git", "checkout", "--", path] 2063 # Checkout message goes to stderr 2064 return _git_run( 2065 command, 2066 cwd=cwd, 2067 user=user, 2068 password=password, 2069 ignore_retcode=ignore_retcode, 2070 redirect_stderr=True, 2071 output_encoding=output_encoding, 2072 )["stdout"] 2073 2074 2075def fetch( 2076 cwd, 2077 remote=None, 2078 force=False, 2079 refspecs=None, 2080 opts="", 2081 git_opts="", 2082 user=None, 2083 password=None, 2084 identity=None, 2085 ignore_retcode=False, 2086 saltenv="base", 2087 output_encoding=None, 2088): 2089 """ 2090 .. versionchanged:: 2015.8.2 2091 Return data is now a dictionary containing information on branches and 2092 tags that were added/updated 2093 2094 Interface to `git-fetch(1)`_ 2095 2096 cwd 2097 The path to the git checkout 2098 2099 remote 2100 Optional remote name to fetch. If not passed, then git will use its 2101 default behavior (as detailed in `git-fetch(1)`_). 2102 2103 .. versionadded:: 2015.8.0 2104 2105 force 2106 Force the fetch even when it is not a fast-forward. 2107 2108 .. versionadded:: 2015.8.0 2109 2110 refspecs 2111 Override the refspec(s) configured for the remote with this argument. 2112 Multiple refspecs can be passed, comma-separated. 2113 2114 .. versionadded:: 2015.8.0 2115 2116 opts 2117 Any additional options to add to the command line, in a single string 2118 2119 .. note:: 2120 On the Salt CLI, if the opts are preceded with a dash, it is 2121 necessary to precede them with ``opts=`` (as in the CLI examples 2122 below) to avoid causing errors with Salt's own argument parsing. 2123 2124 git_opts 2125 Any additional options to add to git command itself (not the ``fetch`` 2126 subcommand), in a single string. This is useful for passing ``-c`` to 2127 run git with temporary changes to the git configuration. 2128 2129 .. versionadded:: 2017.7.0 2130 2131 .. note:: 2132 This is only supported in git 1.7.2 and newer. 2133 2134 user 2135 User under which to run the git command. By default, the command is run 2136 by the user under which the minion is running. 2137 2138 password 2139 Windows only. Required when specifying ``user``. This parameter will be 2140 ignored on non-Windows platforms. 2141 2142 .. versionadded:: 2016.3.4 2143 2144 identity 2145 Path to a private key to use for ssh URLs 2146 2147 .. warning:: 2148 2149 Unless Salt is invoked from the minion using ``salt-call``, the 2150 key(s) must be passphraseless. For greater security with 2151 passphraseless private keys, see the `sshd(8)`_ manpage for 2152 information on securing the keypair from the remote side in the 2153 ``authorized_keys`` file. 2154 2155 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 2156 2157 .. versionchanged:: 2015.8.7 2158 2159 Salt will no longer attempt to use passphrase-protected keys unless 2160 invoked from the minion using ``salt-call``, to prevent blocking 2161 waiting for user input. 2162 2163 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 2164 2165 .. versionchanged:: 2016.3.0 2166 2167 ignore_retcode : False 2168 If ``True``, do not log an error to the minion log if the git command 2169 returns a nonzero exit status. 2170 2171 .. versionadded:: 2015.8.0 2172 2173 saltenv 2174 The default salt environment to pull sls files from 2175 2176 .. versionadded:: 2016.3.1 2177 2178 output_encoding 2179 Use this option to specify which encoding to use to decode the output 2180 from any git commands which are run. This should not be needed in most 2181 cases. 2182 2183 .. note:: 2184 This should only be needed if the files in the repository were 2185 created with filenames using an encoding other than UTF-8 to handle 2186 Unicode characters. 2187 2188 .. versionadded:: 2018.3.1 2189 2190 .. _`git-fetch(1)`: http://git-scm.com/docs/git-fetch 2191 2192 CLI Example: 2193 2194 .. code-block:: bash 2195 2196 salt myminion git.fetch /path/to/repo upstream 2197 salt myminion git.fetch /path/to/repo identity=/root/.ssh/id_rsa 2198 """ 2199 cwd = _expand_path(cwd, user) 2200 command = ["git"] + _format_git_opts(git_opts) 2201 command.append("fetch") 2202 if force: 2203 command.append("--force") 2204 command.extend([x for x in _format_opts(opts) if x not in ("-f", "--force")]) 2205 if remote: 2206 command.append(remote) 2207 if refspecs is not None: 2208 if not isinstance(refspecs, (list, tuple)): 2209 try: 2210 refspecs = refspecs.split(",") 2211 except AttributeError: 2212 refspecs = str(refspecs).split(",") 2213 refspecs = salt.utils.data.stringify(refspecs) 2214 command.extend(refspecs) 2215 output = _git_run( 2216 command, 2217 cwd=cwd, 2218 user=user, 2219 password=password, 2220 identity=identity, 2221 ignore_retcode=ignore_retcode, 2222 redirect_stderr=True, 2223 saltenv=saltenv, 2224 output_encoding=output_encoding, 2225 )["stdout"] 2226 2227 update_re = re.compile( 2228 r"[\s*]*(?:([0-9a-f]+)\.\.([0-9a-f]+)|" 2229 r"\[(?:new (tag|branch)|tag update)\])\s+(.+)->" 2230 ) 2231 ret = {} 2232 for line in salt.utils.itertools.split(output, "\n"): 2233 match = update_re.match(line) 2234 if match: 2235 old_sha, new_sha, new_ref_type, ref_name = match.groups() 2236 ref_name = ref_name.rstrip() 2237 if new_ref_type is not None: 2238 # ref is a new tag/branch 2239 ref_key = "new tags" if new_ref_type == "tag" else "new branches" 2240 ret.setdefault(ref_key, []).append(ref_name) 2241 elif old_sha is not None: 2242 # ref is a branch update 2243 ret.setdefault("updated branches", {})[ref_name] = { 2244 "old": old_sha, 2245 "new": new_sha, 2246 } 2247 else: 2248 # ref is an updated tag 2249 ret.setdefault("updated tags", []).append(ref_name) 2250 return ret 2251 2252 2253def init( 2254 cwd, 2255 bare=False, 2256 template=None, 2257 separate_git_dir=None, 2258 shared=None, 2259 opts="", 2260 git_opts="", 2261 user=None, 2262 password=None, 2263 ignore_retcode=False, 2264 output_encoding=None, 2265): 2266 """ 2267 Interface to `git-init(1)`_ 2268 2269 cwd 2270 The path to the directory to be initialized 2271 2272 bare : False 2273 If ``True``, init a bare repository 2274 2275 .. versionadded:: 2015.8.0 2276 2277 template 2278 Set this argument to specify an alternate `template directory`_ 2279 2280 .. versionadded:: 2015.8.0 2281 2282 separate_git_dir 2283 Set this argument to specify an alternate ``$GIT_DIR`` 2284 2285 .. versionadded:: 2015.8.0 2286 2287 shared 2288 Set sharing permissions on git repo. See `git-init(1)`_ for more 2289 details. 2290 2291 .. versionadded:: 2015.8.0 2292 2293 opts 2294 Any additional options to add to the command line, in a single string 2295 2296 .. note:: 2297 On the Salt CLI, if the opts are preceded with a dash, it is 2298 necessary to precede them with ``opts=`` (as in the CLI examples 2299 below) to avoid causing errors with Salt's own argument parsing. 2300 2301 git_opts 2302 Any additional options to add to git command itself (not the ``init`` 2303 subcommand), in a single string. This is useful for passing ``-c`` to 2304 run git with temporary changes to the git configuration. 2305 2306 .. versionadded:: 2017.7.0 2307 2308 .. note:: 2309 This is only supported in git 1.7.2 and newer. 2310 2311 user 2312 User under which to run the git command. By default, the command is run 2313 by the user under which the minion is running. 2314 2315 password 2316 Windows only. Required when specifying ``user``. This parameter will be 2317 ignored on non-Windows platforms. 2318 2319 .. versionadded:: 2016.3.4 2320 2321 ignore_retcode : False 2322 If ``True``, do not log an error to the minion log if the git command 2323 returns a nonzero exit status. 2324 2325 .. versionadded:: 2015.8.0 2326 2327 output_encoding 2328 Use this option to specify which encoding to use to decode the output 2329 from any git commands which are run. This should not be needed in most 2330 cases. 2331 2332 .. note:: 2333 This should only be needed if the files in the repository were 2334 created with filenames using an encoding other than UTF-8 to handle 2335 Unicode characters. 2336 2337 .. versionadded:: 2018.3.1 2338 2339 .. _`git-init(1)`: http://git-scm.com/docs/git-init 2340 .. _`template directory`: http://git-scm.com/docs/git-init#_template_directory 2341 2342 CLI Examples: 2343 2344 .. code-block:: bash 2345 2346 salt myminion git.init /path/to/repo 2347 # Init a bare repo (before 2015.8.0) 2348 salt myminion git.init /path/to/bare/repo.git opts='--bare' 2349 # Init a bare repo (2015.8.0 and later) 2350 salt myminion git.init /path/to/bare/repo.git bare=True 2351 """ 2352 cwd = _expand_path(cwd, user) 2353 command = ["git"] + _format_git_opts(git_opts) 2354 command.append("init") 2355 if bare: 2356 command.append("--bare") 2357 if template is not None: 2358 command.append("--template={}".format(template)) 2359 if separate_git_dir is not None: 2360 command.append("--separate-git-dir={}".format(separate_git_dir)) 2361 if shared is not None: 2362 if isinstance(shared, int) and not isinstance(shared, bool): 2363 shared = "0" + str(shared) 2364 elif not isinstance(shared, str): 2365 # Using lower here because booleans would be capitalized when 2366 # converted to a string. 2367 shared = str(shared).lower() 2368 command.append("--shared={}".format(shared)) 2369 command.extend(_format_opts(opts)) 2370 command.append(cwd) 2371 return _git_run( 2372 command, 2373 user=user, 2374 password=password, 2375 ignore_retcode=ignore_retcode, 2376 output_encoding=output_encoding, 2377 )["stdout"] 2378 2379 2380def is_worktree(cwd, user=None, password=None, output_encoding=None): 2381 """ 2382 .. versionadded:: 2015.8.0 2383 2384 This function will attempt to determine if ``cwd`` is part of a 2385 worktree by checking its ``.git`` to see if it is a file containing a 2386 reference to another gitdir. 2387 2388 cwd 2389 path to the worktree to be removed 2390 2391 user 2392 User under which to run the git command. By default, the command is run 2393 by the user under which the minion is running. 2394 2395 password 2396 Windows only. Required when specifying ``user``. This parameter will be 2397 ignored on non-Windows platforms. 2398 2399 .. versionadded:: 2016.3.4 2400 2401 output_encoding 2402 Use this option to specify which encoding to use to decode the output 2403 from any git commands which are run. This should not be needed in most 2404 cases. 2405 2406 .. note:: 2407 This should only be needed if the files in the repository were 2408 created with filenames using an encoding other than UTF-8 to handle 2409 Unicode characters. 2410 2411 .. versionadded:: 2018.3.1 2412 2413 CLI Example: 2414 2415 .. code-block:: bash 2416 2417 salt myminion git.is_worktree /path/to/repo 2418 """ 2419 cwd = _expand_path(cwd, user) 2420 try: 2421 toplevel = _get_toplevel( 2422 cwd, user=user, password=password, output_encoding=output_encoding 2423 ) 2424 except CommandExecutionError: 2425 return False 2426 gitdir = os.path.join(toplevel, ".git") 2427 try: 2428 with salt.utils.files.fopen(gitdir, "r") as fp_: 2429 for line in fp_: 2430 line = salt.utils.stringutils.to_unicode(line) 2431 try: 2432 label, path = line.split(None, 1) 2433 except ValueError: 2434 return False 2435 else: 2436 # This file should only contain a single line. However, we 2437 # loop here to handle the corner case where .git is a large 2438 # binary file, so that we do not read the entire file into 2439 # memory at once. We'll hit a return statement before this 2440 # loop enters a second iteration. 2441 if label == "gitdir:" and os.path.isabs(path): 2442 return True 2443 else: 2444 return False 2445 except OSError: 2446 return False 2447 return False 2448 2449 2450def list_branches( 2451 cwd, 2452 remote=False, 2453 user=None, 2454 password=None, 2455 ignore_retcode=False, 2456 output_encoding=None, 2457): 2458 """ 2459 .. versionadded:: 2015.8.0 2460 2461 Return a list of branches 2462 2463 cwd 2464 The path to the git checkout 2465 2466 remote : False 2467 If ``True``, list remote branches. Otherwise, local branches will be 2468 listed. 2469 2470 .. warning:: 2471 2472 This option will only return remote branches of which the local 2473 checkout is aware, use :py:func:`git.fetch 2474 <salt.modules.git.fetch>` to update remotes. 2475 2476 user 2477 User under which to run the git command. By default, the command is run 2478 by the user under which the minion is running. 2479 2480 password 2481 Windows only. Required when specifying ``user``. This parameter will be 2482 ignored on non-Windows platforms. 2483 2484 .. versionadded:: 2016.3.4 2485 2486 ignore_retcode : False 2487 If ``True``, do not log an error to the minion log if the git command 2488 returns a nonzero exit status. 2489 2490 .. versionadded:: 2015.8.0 2491 2492 output_encoding 2493 Use this option to specify which encoding to use to decode the output 2494 from any git commands which are run. This should not be needed in most 2495 cases. 2496 2497 .. note:: 2498 This should only be needed if the files in the repository were 2499 created with filenames using an encoding other than UTF-8 to handle 2500 Unicode characters. 2501 2502 .. versionadded:: 2018.3.1 2503 2504 CLI Examples: 2505 2506 .. code-block:: bash 2507 2508 salt myminion git.list_branches /path/to/repo 2509 salt myminion git.list_branches /path/to/repo remote=True 2510 """ 2511 cwd = _expand_path(cwd, user) 2512 command = [ 2513 "git", 2514 "for-each-ref", 2515 "--format", 2516 "%(refname:short)", 2517 "refs/{}/".format("heads" if not remote else "remotes"), 2518 ] 2519 return _git_run( 2520 command, 2521 cwd=cwd, 2522 user=user, 2523 password=password, 2524 ignore_retcode=ignore_retcode, 2525 output_encoding=output_encoding, 2526 )["stdout"].splitlines() 2527 2528 2529def list_tags( 2530 cwd, user=None, password=None, ignore_retcode=False, output_encoding=None 2531): 2532 """ 2533 .. versionadded:: 2015.8.0 2534 2535 Return a list of tags 2536 2537 cwd 2538 The path to the git checkout 2539 2540 user 2541 User under which to run the git command. By default, the command is run 2542 by the user under which the minion is running. 2543 2544 password 2545 Windows only. Required when specifying ``user``. This parameter will be 2546 ignored on non-Windows platforms. 2547 2548 .. versionadded:: 2016.3.4 2549 2550 ignore_retcode : False 2551 If ``True``, do not log an error to the minion log if the git command 2552 returns a nonzero exit status. 2553 2554 .. versionadded:: 2015.8.0 2555 2556 output_encoding 2557 Use this option to specify which encoding to use to decode the output 2558 from any git commands which are run. This should not be needed in most 2559 cases. 2560 2561 .. note:: 2562 This should only be needed if the files in the repository were 2563 created with filenames using an encoding other than UTF-8 to handle 2564 Unicode characters. 2565 2566 .. versionadded:: 2018.3.1 2567 2568 CLI Examples: 2569 2570 .. code-block:: bash 2571 2572 salt myminion git.list_tags /path/to/repo 2573 """ 2574 cwd = _expand_path(cwd, user) 2575 command = ["git", "for-each-ref", "--format", "%(refname:short)", "refs/tags/"] 2576 return _git_run( 2577 command, 2578 cwd=cwd, 2579 user=user, 2580 password=password, 2581 ignore_retcode=ignore_retcode, 2582 output_encoding=output_encoding, 2583 )["stdout"].splitlines() 2584 2585 2586def list_worktrees( 2587 cwd, stale=False, user=None, password=None, output_encoding=None, **kwargs 2588): 2589 """ 2590 .. versionadded:: 2015.8.0 2591 2592 Returns information on worktrees 2593 2594 .. versionchanged:: 2015.8.4 2595 Version 2.7.0 added the ``list`` subcommand to `git-worktree(1)`_ which 2596 provides a lot of additional information. The return data has been 2597 changed to include this information, even for pre-2.7.0 versions of 2598 git. In addition, if a worktree has a detached head, then any tags 2599 which point to the worktree's HEAD will be included in the return data. 2600 2601 .. note:: 2602 By default, only worktrees for which the worktree directory is still 2603 present are returned, but this can be changed using the ``all`` and 2604 ``stale`` arguments (described below). 2605 2606 cwd 2607 The path to the git checkout 2608 2609 user 2610 User under which to run the git command. By default, the command is run 2611 by the user under which the minion is running. 2612 2613 password 2614 Windows only. Required when specifying ``user``. This parameter will be 2615 ignored on non-Windows platforms. 2616 2617 .. versionadded:: 2016.3.4 2618 2619 all : False 2620 If ``True``, then return all worktrees tracked under 2621 $GIT_DIR/worktrees, including ones for which the gitdir is no longer 2622 present. 2623 2624 stale : False 2625 If ``True``, return *only* worktrees whose gitdir is no longer present. 2626 2627 .. note:: 2628 Only one of ``all`` and ``stale`` can be set to ``True``. 2629 2630 output_encoding 2631 Use this option to specify which encoding to use to decode the output 2632 from any git commands which are run. This should not be needed in most 2633 cases. 2634 2635 .. note:: 2636 This should only be needed if the files in the repository were 2637 created with filenames using an encoding other than UTF-8 to handle 2638 Unicode characters. 2639 2640 .. versionadded:: 2018.3.1 2641 2642 .. _`git-worktree(1)`: http://git-scm.com/docs/git-worktree 2643 2644 CLI Examples: 2645 2646 .. code-block:: bash 2647 2648 salt myminion git.list_worktrees /path/to/repo 2649 salt myminion git.list_worktrees /path/to/repo all=True 2650 salt myminion git.list_worktrees /path/to/repo stale=True 2651 """ 2652 if not _check_worktree_support(failhard=True): 2653 return {} 2654 cwd = _expand_path(cwd, user) 2655 kwargs = salt.utils.args.clean_kwargs(**kwargs) 2656 all_ = kwargs.pop("all", False) 2657 if kwargs: 2658 salt.utils.args.invalid_kwargs(kwargs) 2659 2660 if all_ and stale: 2661 raise CommandExecutionError("'all' and 'stale' cannot both be set to True") 2662 2663 def _git_tag_points_at(cwd, rev, user=None, password=None, output_encoding=None): 2664 """ 2665 Get any tags that point at a 2666 """ 2667 return _git_run( 2668 ["git", "tag", "--points-at", rev], 2669 cwd=cwd, 2670 user=user, 2671 password=password, 2672 output_encoding=output_encoding, 2673 )["stdout"].splitlines() 2674 2675 def _desired(is_stale, all_, stale): 2676 """ 2677 Common logic to determine whether or not to include the worktree info 2678 in the return data. 2679 """ 2680 if is_stale: 2681 if not all_ and not stale: 2682 # Stale worktrees are not desired, skip this one 2683 return False 2684 else: 2685 if stale: 2686 # Only stale worktrees are desired, skip this one 2687 return False 2688 return True 2689 2690 def _duplicate_worktree_path(path): 2691 """ 2692 Log errors to the minion log notifying of duplicate worktree paths. 2693 These should not be there, but may show up due to a bug in git 2.7.0. 2694 """ 2695 log.error( 2696 "git.worktree: Duplicate worktree path %s. This may be caused by " 2697 "a known issue in git 2.7.0 (see " 2698 "http://permalink.gmane.org/gmane.comp.version-control.git/283998)", 2699 path, 2700 ) 2701 2702 tracked_data_points = ("worktree", "HEAD", "branch") 2703 ret = {} 2704 git_version = _LooseVersion(version(versioninfo=False)) 2705 has_native_list_subcommand = git_version >= _LooseVersion("2.7.0") 2706 if has_native_list_subcommand: 2707 out = _git_run( 2708 ["git", "worktree", "list", "--porcelain"], 2709 cwd=cwd, 2710 user=user, 2711 password=password, 2712 output_encoding=output_encoding, 2713 ) 2714 if out["retcode"] != 0: 2715 msg = "Failed to list worktrees" 2716 if out["stderr"]: 2717 msg += ": {}".format(out["stderr"]) 2718 raise CommandExecutionError(msg) 2719 2720 def _untracked_item(line): 2721 """ 2722 Log a warning 2723 """ 2724 log.warning("git.worktree: Untracked line item '%s'", line) 2725 2726 for individual_worktree in salt.utils.itertools.split( 2727 out["stdout"].strip(), "\n\n" 2728 ): 2729 # Initialize the dict where we're storing the tracked data points 2730 worktree_data = {x: "" for x in tracked_data_points} 2731 2732 for line in salt.utils.itertools.split(individual_worktree, "\n"): 2733 try: 2734 type_, value = line.strip().split(None, 1) 2735 except ValueError: 2736 if line == "detached": 2737 type_ = "branch" 2738 value = "detached" 2739 else: 2740 _untracked_item(line) 2741 continue 2742 2743 if type_ not in tracked_data_points: 2744 _untracked_item(line) 2745 continue 2746 2747 if worktree_data[type_]: 2748 log.error( 2749 "git.worktree: Unexpected duplicate %s entry '%s', skipping", 2750 type_, 2751 line, 2752 ) 2753 continue 2754 2755 worktree_data[type_] = value 2756 2757 # Check for missing data points 2758 missing = [x for x in tracked_data_points if not worktree_data[x]] 2759 if missing: 2760 log.error( 2761 "git.worktree: Incomplete worktree data, missing the " 2762 "following information: %s. Full data below:\n%s", 2763 ", ".join(missing), 2764 individual_worktree, 2765 ) 2766 continue 2767 2768 worktree_is_stale = not os.path.isdir(worktree_data["worktree"]) 2769 2770 if not _desired(worktree_is_stale, all_, stale): 2771 continue 2772 2773 if worktree_data["worktree"] in ret: 2774 _duplicate_worktree_path(worktree_data["worktree"]) 2775 2776 wt_ptr = ret.setdefault(worktree_data["worktree"], {}) 2777 wt_ptr["stale"] = worktree_is_stale 2778 wt_ptr["HEAD"] = worktree_data["HEAD"] 2779 wt_ptr["detached"] = worktree_data["branch"] == "detached" 2780 if wt_ptr["detached"]: 2781 wt_ptr["branch"] = None 2782 # Check to see if HEAD points at a tag 2783 tags_found = _git_tag_points_at( 2784 cwd, 2785 wt_ptr["HEAD"], 2786 user=user, 2787 password=password, 2788 output_encoding=output_encoding, 2789 ) 2790 if tags_found: 2791 wt_ptr["tags"] = tags_found 2792 else: 2793 wt_ptr["branch"] = worktree_data["branch"].replace("refs/heads/", "", 1) 2794 2795 return ret 2796 2797 else: 2798 toplevel = _get_toplevel( 2799 cwd, user=user, password=password, output_encoding=output_encoding 2800 ) 2801 try: 2802 worktree_root = rev_parse( 2803 cwd, 2804 opts=["--git-path", "worktrees"], 2805 user=user, 2806 password=password, 2807 output_encoding=output_encoding, 2808 ) 2809 except CommandExecutionError as exc: 2810 msg = "Failed to find worktree location for " + cwd 2811 log.error(msg, exc_info_on_loglevel=logging.DEBUG) 2812 raise CommandExecutionError(msg) 2813 if worktree_root.startswith(".git"): 2814 worktree_root = os.path.join(cwd, worktree_root) 2815 if not os.path.isdir(worktree_root): 2816 raise CommandExecutionError( 2817 "Worktree admin directory {} not present".format(worktree_root) 2818 ) 2819 2820 def _read_file(path): 2821 """ 2822 Return contents of a single line file with EOF newline stripped 2823 """ 2824 try: 2825 with salt.utils.files.fopen(path, "r") as fp_: 2826 for line in fp_: 2827 ret = salt.utils.stringutils.to_unicode(line).strip() 2828 # Ignore other lines, if they exist (which they 2829 # shouldn't) 2830 break 2831 return ret 2832 except OSError as exc: 2833 # Raise a CommandExecutionError 2834 salt.utils.files.process_read_exception(exc, path) 2835 2836 for worktree_name in os.listdir(worktree_root): 2837 admin_dir = os.path.join(worktree_root, worktree_name) 2838 gitdir_file = os.path.join(admin_dir, "gitdir") 2839 head_file = os.path.join(admin_dir, "HEAD") 2840 2841 wt_loc = _read_file(gitdir_file) 2842 head_ref = _read_file(head_file) 2843 2844 if not os.path.isabs(wt_loc): 2845 log.error( 2846 "Non-absolute path found in %s. If git 2.7.0 was " 2847 "installed and then downgraded, this was likely caused " 2848 "by a known issue in git 2.7.0. See " 2849 "http://permalink.gmane.org/gmane.comp.version-control" 2850 ".git/283998 for more information.", 2851 gitdir_file, 2852 ) 2853 # Emulate what 'git worktree list' does under-the-hood, and 2854 # that is using the toplevel directory. It will still give 2855 # inaccurate results, but will avoid a traceback. 2856 wt_loc = toplevel 2857 2858 if wt_loc.endswith("/.git"): 2859 wt_loc = wt_loc[:-5] 2860 2861 worktree_is_stale = not os.path.isdir(wt_loc) 2862 2863 if not _desired(worktree_is_stale, all_, stale): 2864 continue 2865 2866 if wt_loc in ret: 2867 _duplicate_worktree_path(wt_loc) 2868 2869 if head_ref.startswith("ref: "): 2870 head_ref = head_ref.split(None, 1)[-1] 2871 wt_branch = head_ref.replace("refs/heads/", "", 1) 2872 wt_head = rev_parse( 2873 cwd, 2874 rev=head_ref, 2875 user=user, 2876 password=password, 2877 output_encoding=output_encoding, 2878 ) 2879 wt_detached = False 2880 else: 2881 wt_branch = None 2882 wt_head = head_ref 2883 wt_detached = True 2884 2885 wt_ptr = ret.setdefault(wt_loc, {}) 2886 wt_ptr["stale"] = worktree_is_stale 2887 wt_ptr["branch"] = wt_branch 2888 wt_ptr["HEAD"] = wt_head 2889 wt_ptr["detached"] = wt_detached 2890 2891 # Check to see if HEAD points at a tag 2892 if wt_detached: 2893 tags_found = _git_tag_points_at( 2894 cwd, 2895 wt_head, 2896 user=user, 2897 password=password, 2898 output_encoding=output_encoding, 2899 ) 2900 if tags_found: 2901 wt_ptr["tags"] = tags_found 2902 2903 return ret 2904 2905 2906def ls_remote( 2907 cwd=None, 2908 remote="origin", 2909 ref=None, 2910 opts="", 2911 git_opts="", 2912 user=None, 2913 password=None, 2914 identity=None, 2915 https_user=None, 2916 https_pass=None, 2917 ignore_retcode=False, 2918 output_encoding=None, 2919 saltenv="base", 2920): 2921 """ 2922 Interface to `git-ls-remote(1)`_. Returns the upstream hash for a remote 2923 reference. 2924 2925 cwd 2926 The path to the git checkout. Optional (and ignored if present) when 2927 ``remote`` is set to a URL instead of a remote name. 2928 2929 remote : origin 2930 The name of the remote to query. Can be the name of a git remote 2931 (which exists in the git checkout defined by the ``cwd`` parameter), 2932 or the URL of a remote repository. 2933 2934 .. versionchanged:: 2015.8.0 2935 Argument renamed from ``repository`` to ``remote`` 2936 2937 ref 2938 The name of the ref to query. Optional, if not specified, all refs are 2939 returned. Can be a branch or tag name, or the full name of the 2940 reference (for example, to get the hash for a Github pull request number 2941 1234, ``ref`` can be set to ``refs/pull/1234/head`` 2942 2943 .. versionchanged:: 2015.8.0 2944 Argument renamed from ``branch`` to ``ref`` 2945 2946 .. versionchanged:: 2015.8.4 2947 Defaults to returning all refs instead of master. 2948 2949 opts 2950 Any additional options to add to the command line, in a single string 2951 2952 .. versionadded:: 2015.8.0 2953 2954 git_opts 2955 Any additional options to add to git command itself (not the 2956 ``ls-remote`` subcommand), in a single string. This is useful for 2957 passing ``-c`` to run git with temporary changes to the git 2958 configuration. 2959 2960 .. versionadded:: 2017.7.0 2961 2962 .. note:: 2963 This is only supported in git 1.7.2 and newer. 2964 2965 user 2966 User under which to run the git command. By default, the command is run 2967 by the user under which the minion is running. 2968 2969 password 2970 Windows only. Required when specifying ``user``. This parameter will be 2971 ignored on non-Windows platforms. 2972 2973 .. versionadded:: 2016.3.4 2974 2975 identity 2976 Path to a private key to use for ssh URLs 2977 2978 .. warning:: 2979 2980 Unless Salt is invoked from the minion using ``salt-call``, the 2981 key(s) must be passphraseless. For greater security with 2982 passphraseless private keys, see the `sshd(8)`_ manpage for 2983 information on securing the keypair from the remote side in the 2984 ``authorized_keys`` file. 2985 2986 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 2987 2988 .. versionchanged:: 2015.8.7 2989 2990 Salt will no longer attempt to use passphrase-protected keys unless 2991 invoked from the minion using ``salt-call``, to prevent blocking 2992 waiting for user input. 2993 2994 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 2995 2996 .. versionchanged:: 2016.3.0 2997 2998 https_user 2999 Set HTTP Basic Auth username. Only accepted for HTTPS URLs. 3000 3001 .. versionadded:: 2015.5.0 3002 3003 https_pass 3004 Set HTTP Basic Auth password. Only accepted for HTTPS URLs. 3005 3006 .. versionadded:: 2015.5.0 3007 3008 ignore_retcode : False 3009 If ``True``, do not log an error to the minion log if the git command 3010 returns a nonzero exit status. 3011 3012 .. versionadded:: 2015.8.0 3013 3014 saltenv 3015 The default salt environment to pull sls files from 3016 3017 .. versionadded:: 2016.3.1 3018 3019 output_encoding 3020 Use this option to specify which encoding to use to decode the output 3021 from any git commands which are run. This should not be needed in most 3022 cases. 3023 3024 .. note:: 3025 This should only be needed if the files in the repository were 3026 created with filenames using an encoding other than UTF-8 to handle 3027 Unicode characters. 3028 3029 .. versionadded:: 2018.3.1 3030 3031 .. _`git-ls-remote(1)`: http://git-scm.com/docs/git-ls-remote 3032 3033 CLI Example: 3034 3035 .. code-block:: bash 3036 3037 salt myminion git.ls_remote /path/to/repo origin master 3038 salt myminion git.ls_remote remote=https://mydomain.tld/repo.git ref=mytag opts='--tags' 3039 """ 3040 if cwd is not None: 3041 cwd = _expand_path(cwd, user) 3042 try: 3043 remote = salt.utils.url.add_http_basic_auth( 3044 remote, https_user, https_pass, https_only=True 3045 ) 3046 except ValueError as exc: 3047 raise SaltInvocationError(exc.__str__()) 3048 command = ["git"] + _format_git_opts(git_opts) 3049 command.append("ls-remote") 3050 command.extend(_format_opts(opts)) 3051 command.append(remote) 3052 if ref: 3053 command.append(ref) 3054 output = _git_run( 3055 command, 3056 cwd=cwd, 3057 user=user, 3058 password=password, 3059 identity=identity, 3060 ignore_retcode=ignore_retcode, 3061 saltenv=saltenv, 3062 output_encoding=output_encoding, 3063 )["stdout"] 3064 ret = {} 3065 for line in output.splitlines(): 3066 try: 3067 ref_sha1, ref_name = line.split(None, 1) 3068 except IndexError: 3069 continue 3070 ret[ref_name] = ref_sha1 3071 return ret 3072 3073 3074def merge( 3075 cwd, 3076 rev=None, 3077 opts="", 3078 git_opts="", 3079 user=None, 3080 password=None, 3081 identity=None, 3082 ignore_retcode=False, 3083 output_encoding=None, 3084 **kwargs 3085): 3086 """ 3087 Interface to `git-merge(1)`_ 3088 3089 cwd 3090 The path to the git checkout 3091 3092 rev 3093 Revision to merge into the current branch. If not specified, the remote 3094 tracking branch will be merged. 3095 3096 .. versionadded:: 2015.8.0 3097 3098 opts 3099 Any additional options to add to the command line, in a single string 3100 3101 .. note:: 3102 On the Salt CLI, if the opts are preceded with a dash, it is 3103 necessary to precede them with ``opts=`` (as in the CLI examples 3104 below) to avoid causing errors with Salt's own argument parsing. 3105 3106 git_opts 3107 Any additional options to add to git command itself (not the ``merge`` 3108 subcommand), in a single string. This is useful for passing ``-c`` to 3109 run git with temporary changes to the git configuration. 3110 3111 .. versionadded:: 2017.7.0 3112 3113 .. note:: 3114 This is only supported in git 1.7.2 and newer. 3115 3116 user 3117 User under which to run the git command. By default, the command is run 3118 by the user under which the minion is running. 3119 3120 password 3121 Windows only. Required when specifying ``user``. This parameter will be 3122 ignored on non-Windows platforms. 3123 3124 .. versionadded:: 2016.3.4 3125 3126 identity 3127 Path to a private key to use for ssh URLs. Salt will not attempt to use 3128 passphrase-protected keys unless invoked from the minion using 3129 ``salt-call``, to prevent blocking waiting for user input. Key can also 3130 be specified as a SaltStack file server URL, eg. 3131 ``salt://location/identity_file``. 3132 3133 .. note:: 3134 For greater security with passphraseless private keys, see the 3135 `sshd(8)`_ manpage for information on securing the keypair from the 3136 remote side in the ``authorized_keys`` file. 3137 3138 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 3139 3140 .. versionadded:: 2018.3.5,2019.2.1,3000 3141 3142 ignore_retcode : False 3143 If ``True``, do not log an error to the minion log if the git command 3144 returns a nonzero exit status. 3145 3146 .. versionadded:: 2015.8.0 3147 3148 output_encoding 3149 Use this option to specify which encoding to use to decode the output 3150 from any git commands which are run. This should not be needed in most 3151 cases. 3152 3153 .. note:: 3154 This should only be needed if the files in the repository were 3155 created with filenames using an encoding other than UTF-8 to handle 3156 Unicode characters. 3157 3158 .. versionadded:: 2018.3.1 3159 3160 .. _`git-merge(1)`: http://git-scm.com/docs/git-merge 3161 3162 CLI Example: 3163 3164 .. code-block:: bash 3165 3166 # Fetch first... 3167 salt myminion git.fetch /path/to/repo 3168 # ... then merge the remote tracking branch 3169 salt myminion git.merge /path/to/repo 3170 # .. or merge another rev 3171 salt myminion git.merge /path/to/repo rev=upstream/foo 3172 """ 3173 kwargs = salt.utils.args.clean_kwargs(**kwargs) 3174 if kwargs: 3175 salt.utils.args.invalid_kwargs(kwargs) 3176 3177 cwd = _expand_path(cwd, user) 3178 command = ["git"] + _format_git_opts(git_opts) 3179 command.append("merge") 3180 command.extend(_format_opts(opts)) 3181 if rev: 3182 command.append(rev) 3183 3184 return _git_run( 3185 command, 3186 cwd=cwd, 3187 user=user, 3188 password=password, 3189 identity=identity, 3190 ignore_retcode=ignore_retcode, 3191 output_encoding=output_encoding, 3192 )["stdout"] 3193 3194 3195def merge_base( 3196 cwd, 3197 refs=None, 3198 octopus=False, 3199 is_ancestor=False, 3200 independent=False, 3201 fork_point=None, 3202 opts="", 3203 git_opts="", 3204 user=None, 3205 password=None, 3206 ignore_retcode=False, 3207 output_encoding=None, 3208 **kwargs 3209): 3210 """ 3211 .. versionadded:: 2015.8.0 3212 3213 Interface to `git-merge-base(1)`_. 3214 3215 cwd 3216 The path to the git checkout 3217 3218 refs 3219 Any refs/commits to check for a merge base. Can be passed as a 3220 comma-separated list or a Python list. 3221 3222 all : False 3223 Return a list of all matching merge bases. Not compatible with any of 3224 the below options except for ``octopus``. 3225 3226 octopus : False 3227 If ``True``, then this function will determine the best common 3228 ancestors of all specified commits, in preparation for an n-way merge. 3229 See here_ for a description of how these bases are determined. 3230 3231 Set ``all`` to ``True`` with this option to return all computed merge 3232 bases, otherwise only the "best" will be returned. 3233 3234 is_ancestor : False 3235 If ``True``, then instead of returning the merge base, return a 3236 boolean telling whether or not the first commit is an ancestor of the 3237 second commit. 3238 3239 .. note:: 3240 This option requires two commits to be passed. 3241 3242 .. versionchanged:: 2015.8.2 3243 Works properly in git versions older than 1.8.0, where the 3244 ``--is-ancestor`` CLI option is not present. 3245 3246 independent : False 3247 If ``True``, this function will return the IDs of the refs/commits 3248 passed which cannot be reached by another commit. 3249 3250 fork_point 3251 If passed, then this function will return the commit where the 3252 commit diverged from the ref specified by ``fork_point``. If no fork 3253 point is found, ``None`` is returned. 3254 3255 .. note:: 3256 At most one commit is permitted to be passed if a ``fork_point`` is 3257 specified. If no commits are passed, then ``HEAD`` is assumed. 3258 3259 opts 3260 Any additional options to add to the command line, in a single string 3261 3262 .. note:: 3263 On the Salt CLI, if the opts are preceded with a dash, it is 3264 necessary to precede them with ``opts=`` (as in the CLI examples 3265 below) to avoid causing errors with Salt's own argument parsing. 3266 3267 This option should not be necessary unless new CLI arguments are 3268 added to `git-merge-base(1)`_ and are not yet supported in Salt. 3269 3270 git_opts 3271 Any additional options to add to git command itself (not the 3272 ``merge-base`` subcommand), in a single string. This is useful for 3273 passing ``-c`` to run git with temporary changes to the git 3274 configuration. 3275 3276 .. versionadded:: 2017.7.0 3277 3278 .. note:: 3279 This is only supported in git 1.7.2 and newer. 3280 3281 user 3282 User under which to run the git command. By default, the command is run 3283 by the user under which the minion is running. 3284 3285 password 3286 Windows only. Required when specifying ``user``. This parameter will be 3287 ignored on non-Windows platforms. 3288 3289 .. versionadded:: 2016.3.4 3290 3291 ignore_retcode : False 3292 if ``True``, do not log an error to the minion log if the git command 3293 returns a nonzero exit status. 3294 3295 output_encoding 3296 Use this option to specify which encoding to use to decode the output 3297 from any git commands which are run. This should not be needed in most 3298 cases. 3299 3300 .. note:: 3301 This should only be needed if the files in the repository were 3302 created with filenames using an encoding other than UTF-8 to handle 3303 Unicode characters. 3304 3305 .. versionadded:: 2018.3.1 3306 3307 .. _`git-merge-base(1)`: http://git-scm.com/docs/git-merge-base 3308 .. _here: http://git-scm.com/docs/git-merge-base#_discussion 3309 3310 CLI Examples: 3311 3312 .. code-block:: bash 3313 3314 salt myminion git.merge_base /path/to/repo HEAD upstream/mybranch 3315 salt myminion git.merge_base /path/to/repo 8f2e542,4ad8cab,cdc9886 octopus=True 3316 salt myminion git.merge_base /path/to/repo refs=8f2e542,4ad8cab,cdc9886 independent=True 3317 salt myminion git.merge_base /path/to/repo refs=8f2e542,4ad8cab is_ancestor=True 3318 salt myminion git.merge_base /path/to/repo fork_point=upstream/master 3319 salt myminion git.merge_base /path/to/repo refs=mybranch fork_point=upstream/master 3320 """ 3321 cwd = _expand_path(cwd, user) 3322 kwargs = salt.utils.args.clean_kwargs(**kwargs) 3323 all_ = kwargs.pop("all", False) 3324 if kwargs: 3325 salt.utils.args.invalid_kwargs(kwargs) 3326 3327 if all_ and (independent or is_ancestor or fork_point): 3328 raise SaltInvocationError( 3329 "The 'all' argument is not compatible with 'independent', " 3330 "'is_ancestor', or 'fork_point'" 3331 ) 3332 3333 if refs is None: 3334 refs = [] 3335 elif not isinstance(refs, (list, tuple)): 3336 refs = [x.strip() for x in str(refs).split(",")] 3337 mutually_exclusive_count = len( 3338 [x for x in (octopus, independent, is_ancestor, fork_point) if x] 3339 ) 3340 if mutually_exclusive_count > 1: 3341 raise SaltInvocationError( 3342 "Only one of 'octopus', 'independent', 'is_ancestor', and " 3343 "'fork_point' is permitted" 3344 ) 3345 elif is_ancestor: 3346 if len(refs) != 2: 3347 raise SaltInvocationError( 3348 "Two refs/commits are required if 'is_ancestor' is True" 3349 ) 3350 elif fork_point: 3351 if len(refs) > 1: 3352 raise SaltInvocationError( 3353 "At most one ref/commit can be passed if 'fork_point' is specified" 3354 ) 3355 elif not refs: 3356 refs = ["HEAD"] 3357 3358 if is_ancestor: 3359 if _LooseVersion(version(versioninfo=False)) < _LooseVersion("1.8.0"): 3360 # Pre 1.8.0 git doesn't have --is-ancestor, so the logic here is a 3361 # little different. First we need to resolve the first ref to a 3362 # full SHA1, and then if running git merge-base on both commits 3363 # returns an identical commit to the resolved first ref, we know 3364 # that the first ref is an ancestor of the second ref. 3365 first_commit = rev_parse( 3366 cwd, 3367 rev=refs[0], 3368 opts=["--verify"], 3369 user=user, 3370 password=password, 3371 ignore_retcode=ignore_retcode, 3372 output_encoding=output_encoding, 3373 ) 3374 return ( 3375 merge_base( 3376 cwd, 3377 refs=refs, 3378 is_ancestor=False, 3379 user=user, 3380 password=password, 3381 ignore_retcode=ignore_retcode, 3382 output_encoding=output_encoding, 3383 ) 3384 == first_commit 3385 ) 3386 3387 command = ["git"] + _format_git_opts(git_opts) 3388 command.append("merge-base") 3389 command.extend(_format_opts(opts)) 3390 if all_: 3391 command.append("--all") 3392 if octopus: 3393 command.append("--octopus") 3394 elif is_ancestor: 3395 command.append("--is-ancestor") 3396 elif independent: 3397 command.append("--independent") 3398 elif fork_point: 3399 command.extend(["--fork-point", fork_point]) 3400 command.extend(refs) 3401 result = _git_run( 3402 command, 3403 cwd=cwd, 3404 user=user, 3405 password=password, 3406 ignore_retcode=ignore_retcode, 3407 failhard=False if is_ancestor else True, 3408 output_encoding=output_encoding, 3409 ) 3410 if is_ancestor: 3411 return result["retcode"] == 0 3412 all_bases = result["stdout"].splitlines() 3413 if all_: 3414 return all_bases 3415 return all_bases[0] 3416 3417 3418def merge_tree( 3419 cwd, 3420 ref1, 3421 ref2, 3422 base=None, 3423 user=None, 3424 password=None, 3425 ignore_retcode=False, 3426 output_encoding=None, 3427): 3428 """ 3429 .. versionadded:: 2015.8.0 3430 3431 Interface to `git-merge-tree(1)`_, shows the merge results and conflicts 3432 from a 3-way merge without touching the index. 3433 3434 cwd 3435 The path to the git checkout 3436 3437 ref1 3438 First ref/commit to compare 3439 3440 ref2 3441 Second ref/commit to compare 3442 3443 base 3444 The base tree to use for the 3-way-merge. If not provided, then 3445 :py:func:`git.merge_base <salt.modules.git.merge_base>` will be invoked 3446 on ``ref1`` and ``ref2`` to determine the merge base to use. 3447 3448 user 3449 User under which to run the git command. By default, the command is run 3450 by the user under which the minion is running. 3451 3452 password 3453 Windows only. Required when specifying ``user``. This parameter will be 3454 ignored on non-Windows platforms. 3455 3456 .. versionadded:: 2016.3.4 3457 3458 ignore_retcode : False 3459 if ``True``, do not log an error to the minion log if the git command 3460 returns a nonzero exit status. 3461 3462 output_encoding 3463 Use this option to specify which encoding to use to decode the output 3464 from any git commands which are run. This should not be needed in most 3465 cases. 3466 3467 .. note:: 3468 This should only be needed if the files in the repository were 3469 created with filenames using an encoding other than UTF-8 to handle 3470 Unicode characters. 3471 3472 .. versionadded:: 2018.3.1 3473 3474 .. _`git-merge-tree(1)`: http://git-scm.com/docs/git-merge-tree 3475 3476 CLI Examples: 3477 3478 .. code-block:: bash 3479 3480 salt myminion git.merge_tree /path/to/repo HEAD upstream/dev 3481 salt myminion git.merge_tree /path/to/repo HEAD upstream/dev base=aaf3c3d 3482 """ 3483 cwd = _expand_path(cwd, user) 3484 command = ["git", "merge-tree"] 3485 if base is None: 3486 try: 3487 base = merge_base(cwd, refs=[ref1, ref2], output_encoding=output_encoding) 3488 except (SaltInvocationError, CommandExecutionError): 3489 raise CommandExecutionError( 3490 "Unable to determine merge base for {} and {}".format(ref1, ref2) 3491 ) 3492 command.extend([base, ref1, ref2]) 3493 return _git_run( 3494 command, 3495 cwd=cwd, 3496 user=user, 3497 password=password, 3498 ignore_retcode=ignore_retcode, 3499 output_encoding=output_encoding, 3500 )["stdout"] 3501 3502 3503def pull( 3504 cwd, 3505 opts="", 3506 git_opts="", 3507 user=None, 3508 password=None, 3509 identity=None, 3510 ignore_retcode=False, 3511 saltenv="base", 3512 output_encoding=None, 3513): 3514 """ 3515 Interface to `git-pull(1)`_ 3516 3517 cwd 3518 The path to the git checkout 3519 3520 opts 3521 Any additional options to add to the command line, in a single string 3522 3523 .. note:: 3524 On the Salt CLI, if the opts are preceded with a dash, it is 3525 necessary to precede them with ``opts=`` (as in the CLI examples 3526 below) to avoid causing errors with Salt's own argument parsing. 3527 3528 git_opts 3529 Any additional options to add to git command itself (not the ``pull`` 3530 subcommand), in a single string. This is useful for passing ``-c`` to 3531 run git with temporary changes to the git configuration. 3532 3533 .. versionadded:: 2017.7.0 3534 3535 .. note:: 3536 This is only supported in git 1.7.2 and newer. 3537 3538 user 3539 User under which to run the git command. By default, the command is run 3540 by the user under which the minion is running. 3541 3542 password 3543 Windows only. Required when specifying ``user``. This parameter will be 3544 ignored on non-Windows platforms. 3545 3546 .. versionadded:: 2016.3.4 3547 3548 identity 3549 Path to a private key to use for ssh URLs 3550 3551 .. warning:: 3552 3553 Unless Salt is invoked from the minion using ``salt-call``, the 3554 key(s) must be passphraseless. For greater security with 3555 passphraseless private keys, see the `sshd(8)`_ manpage for 3556 information on securing the keypair from the remote side in the 3557 ``authorized_keys`` file. 3558 3559 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 3560 3561 .. versionchanged:: 2015.8.7 3562 3563 Salt will no longer attempt to use passphrase-protected keys unless 3564 invoked from the minion using ``salt-call``, to prevent blocking 3565 waiting for user input. 3566 3567 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 3568 3569 .. versionchanged:: 2016.3.0 3570 3571 ignore_retcode : False 3572 If ``True``, do not log an error to the minion log if the git command 3573 returns a nonzero exit status. 3574 3575 .. versionadded:: 2015.8.0 3576 3577 saltenv 3578 The default salt environment to pull sls files from 3579 3580 .. versionadded:: 2016.3.1 3581 3582 output_encoding 3583 Use this option to specify which encoding to use to decode the output 3584 from any git commands which are run. This should not be needed in most 3585 cases. 3586 3587 .. note:: 3588 This should only be needed if the files in the repository were 3589 created with filenames using an encoding other than UTF-8 to handle 3590 Unicode characters. 3591 3592 .. versionadded:: 2018.3.1 3593 3594 .. _`git-pull(1)`: http://git-scm.com/docs/git-pull 3595 3596 CLI Example: 3597 3598 .. code-block:: bash 3599 3600 salt myminion git.pull /path/to/repo opts='--rebase origin master' 3601 """ 3602 cwd = _expand_path(cwd, user) 3603 command = ["git"] + _format_git_opts(git_opts) 3604 command.append("pull") 3605 command.extend(_format_opts(opts)) 3606 return _git_run( 3607 command, 3608 cwd=cwd, 3609 user=user, 3610 password=password, 3611 identity=identity, 3612 ignore_retcode=ignore_retcode, 3613 saltenv=saltenv, 3614 output_encoding=output_encoding, 3615 )["stdout"] 3616 3617 3618def push( 3619 cwd, 3620 remote=None, 3621 ref=None, 3622 opts="", 3623 git_opts="", 3624 user=None, 3625 password=None, 3626 identity=None, 3627 ignore_retcode=False, 3628 saltenv="base", 3629 output_encoding=None, 3630 **kwargs 3631): 3632 """ 3633 Interface to `git-push(1)`_ 3634 3635 cwd 3636 The path to the git checkout 3637 3638 remote 3639 Name of the remote to which the ref should being pushed 3640 3641 .. versionadded:: 2015.8.0 3642 3643 ref : master 3644 Name of the ref to push 3645 3646 .. note:: 3647 Being a refspec_, this argument can include a colon to define local 3648 and remote ref names. 3649 3650 opts 3651 Any additional options to add to the command line, in a single string 3652 3653 .. note:: 3654 On the Salt CLI, if the opts are preceded with a dash, it is 3655 necessary to precede them with ``opts=`` (as in the CLI examples 3656 below) to avoid causing errors with Salt's own argument parsing. 3657 3658 git_opts 3659 Any additional options to add to git command itself (not the ``push`` 3660 subcommand), in a single string. This is useful for passing ``-c`` to 3661 run git with temporary changes to the git configuration. 3662 3663 .. versionadded:: 2017.7.0 3664 3665 .. note:: 3666 This is only supported in git 1.7.2 and newer. 3667 3668 user 3669 User under which to run the git command. By default, the command is run 3670 by the user under which the minion is running. 3671 3672 password 3673 Windows only. Required when specifying ``user``. This parameter will be 3674 ignored on non-Windows platforms. 3675 3676 .. versionadded:: 2016.3.4 3677 3678 identity 3679 Path to a private key to use for ssh URLs 3680 3681 .. warning:: 3682 3683 Unless Salt is invoked from the minion using ``salt-call``, the 3684 key(s) must be passphraseless. For greater security with 3685 passphraseless private keys, see the `sshd(8)`_ manpage for 3686 information on securing the keypair from the remote side in the 3687 ``authorized_keys`` file. 3688 3689 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 3690 3691 .. versionchanged:: 2015.8.7 3692 3693 Salt will no longer attempt to use passphrase-protected keys unless 3694 invoked from the minion using ``salt-call``, to prevent blocking 3695 waiting for user input. 3696 3697 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 3698 3699 .. versionchanged:: 2016.3.0 3700 3701 ignore_retcode : False 3702 If ``True``, do not log an error to the minion log if the git command 3703 returns a nonzero exit status. 3704 3705 .. versionadded:: 2015.8.0 3706 3707 saltenv 3708 The default salt environment to pull sls files from 3709 3710 .. versionadded:: 2016.3.1 3711 3712 output_encoding 3713 Use this option to specify which encoding to use to decode the output 3714 from any git commands which are run. This should not be needed in most 3715 cases. 3716 3717 .. note:: 3718 This should only be needed if the files in the repository were 3719 created with filenames using an encoding other than UTF-8 to handle 3720 Unicode characters. 3721 3722 .. versionadded:: 2018.3.1 3723 3724 .. _`git-push(1)`: http://git-scm.com/docs/git-push 3725 .. _refspec: http://git-scm.com/book/en/v2/Git-Internals-The-Refspec 3726 3727 CLI Example: 3728 3729 .. code-block:: bash 3730 3731 # Push master as origin/master 3732 salt myminion git.push /path/to/repo origin master 3733 # Push issue21 as upstream/develop 3734 salt myminion git.push /path/to/repo upstream issue21:develop 3735 # Delete remote branch 'upstream/temp' 3736 salt myminion git.push /path/to/repo upstream :temp 3737 """ 3738 kwargs = salt.utils.args.clean_kwargs(**kwargs) 3739 if kwargs: 3740 salt.utils.args.invalid_kwargs(kwargs) 3741 3742 cwd = _expand_path(cwd, user) 3743 command = ["git"] + _format_git_opts(git_opts) 3744 command.append("push") 3745 command.extend(_format_opts(opts)) 3746 command.extend([remote, ref]) 3747 return _git_run( 3748 command, 3749 cwd=cwd, 3750 user=user, 3751 password=password, 3752 identity=identity, 3753 ignore_retcode=ignore_retcode, 3754 saltenv=saltenv, 3755 output_encoding=output_encoding, 3756 )["stdout"] 3757 3758 3759def rebase( 3760 cwd, 3761 rev="master", 3762 opts="", 3763 git_opts="", 3764 user=None, 3765 password=None, 3766 ignore_retcode=False, 3767 output_encoding=None, 3768): 3769 """ 3770 Interface to `git-rebase(1)`_ 3771 3772 cwd 3773 The path to the git checkout 3774 3775 rev : master 3776 The revision to rebase onto the current branch 3777 3778 opts 3779 Any additional options to add to the command line, in a single string 3780 3781 .. note:: 3782 On the Salt CLI, if the opts are preceded with a dash, it is 3783 necessary to precede them with ``opts=`` (as in the CLI examples 3784 below) to avoid causing errors with Salt's own argument parsing. 3785 3786 git_opts 3787 Any additional options to add to git command itself (not the ``rebase`` 3788 subcommand), in a single string. This is useful for passing ``-c`` to 3789 run git with temporary changes to the git configuration. 3790 3791 .. versionadded:: 2017.7.0 3792 3793 .. note:: 3794 This is only supported in git 1.7.2 and newer. 3795 3796 user 3797 User under which to run the git command. By default, the command is run 3798 by the user under which the minion is running. 3799 3800 password 3801 Windows only. Required when specifying ``user``. This parameter will be 3802 ignored on non-Windows platforms. 3803 3804 .. versionadded:: 2016.3.4 3805 3806 ignore_retcode : False 3807 If ``True``, do not log an error to the minion log if the git command 3808 returns a nonzero exit status. 3809 3810 .. versionadded:: 2015.8.0 3811 3812 output_encoding 3813 Use this option to specify which encoding to use to decode the output 3814 from any git commands which are run. This should not be needed in most 3815 cases. 3816 3817 .. note:: 3818 This should only be needed if the files in the repository were 3819 created with filenames using an encoding other than UTF-8 to handle 3820 Unicode characters. 3821 3822 .. versionadded:: 2018.3.1 3823 3824 .. _`git-rebase(1)`: http://git-scm.com/docs/git-rebase 3825 3826 CLI Example: 3827 3828 .. code-block:: bash 3829 3830 salt myminion git.rebase /path/to/repo master 3831 salt myminion git.rebase /path/to/repo 'origin master' 3832 salt myminion git.rebase /path/to/repo origin/master opts='--onto newbranch' 3833 """ 3834 cwd = _expand_path(cwd, user) 3835 opts = _format_opts(opts) 3836 if any(x for x in opts if x in ("-i", "--interactive")): 3837 raise SaltInvocationError("Interactive rebases are not supported") 3838 command = ["git"] + _format_git_opts(git_opts) 3839 command.append("rebase") 3840 command.extend(opts) 3841 if not isinstance(rev, str): 3842 rev = str(rev) 3843 command.extend(salt.utils.args.shlex_split(rev)) 3844 return _git_run( 3845 command, 3846 cwd=cwd, 3847 user=user, 3848 password=password, 3849 ignore_retcode=ignore_retcode, 3850 output_encoding=output_encoding, 3851 )["stdout"] 3852 3853 3854def remote_get( 3855 cwd, 3856 remote="origin", 3857 user=None, 3858 password=None, 3859 redact_auth=True, 3860 ignore_retcode=False, 3861 output_encoding=None, 3862): 3863 """ 3864 Get the fetch and push URL for a specific remote 3865 3866 cwd 3867 The path to the git checkout 3868 3869 remote : origin 3870 Name of the remote to query 3871 3872 user 3873 User under which to run the git command. By default, the command is run 3874 by the user under which the minion is running. 3875 3876 password 3877 Windows only. Required when specifying ``user``. This parameter will be 3878 ignored on non-Windows platforms. 3879 3880 .. versionadded:: 2016.3.4 3881 3882 redact_auth : True 3883 Set to ``False`` to include the username/password if the remote uses 3884 HTTPS Basic Auth. Otherwise, this information will be redacted. 3885 3886 .. warning:: 3887 Setting this to ``False`` will not only reveal any HTTPS Basic Auth 3888 that is configured, but the return data will also be written to the 3889 job cache. When possible, it is recommended to use SSH for 3890 authentication. 3891 3892 .. versionadded:: 2015.5.6 3893 3894 ignore_retcode : False 3895 If ``True``, do not log an error to the minion log if the git command 3896 returns a nonzero exit status. 3897 3898 .. versionadded:: 2015.8.0 3899 3900 output_encoding 3901 Use this option to specify which encoding to use to decode the output 3902 from any git commands which are run. This should not be needed in most 3903 cases. 3904 3905 .. note:: 3906 This should only be needed if the files in the repository were 3907 created with filenames using an encoding other than UTF-8 to handle 3908 Unicode characters. 3909 3910 .. versionadded:: 2018.3.1 3911 3912 CLI Examples: 3913 3914 .. code-block:: bash 3915 3916 salt myminion git.remote_get /path/to/repo 3917 salt myminion git.remote_get /path/to/repo upstream 3918 """ 3919 cwd = _expand_path(cwd, user) 3920 all_remotes = remotes( 3921 cwd, 3922 user=user, 3923 password=password, 3924 redact_auth=redact_auth, 3925 ignore_retcode=ignore_retcode, 3926 output_encoding=output_encoding, 3927 ) 3928 if remote not in all_remotes: 3929 raise CommandExecutionError( 3930 "Remote '{}' not present in git checkout located at {}".format(remote, cwd) 3931 ) 3932 return all_remotes[remote] 3933 3934 3935def remote_refs( 3936 url, 3937 heads=False, 3938 tags=False, 3939 user=None, 3940 password=None, 3941 identity=None, 3942 https_user=None, 3943 https_pass=None, 3944 ignore_retcode=False, 3945 output_encoding=None, 3946 saltenv="base", 3947 **kwargs 3948): 3949 """ 3950 .. versionadded:: 2015.8.0 3951 3952 Return the remote refs for the specified URL by running ``git ls-remote``. 3953 3954 url 3955 URL of the remote repository 3956 3957 filter 3958 Optionally provide a ref name to ``git ls-remote``. This can be useful 3959 to make this function run faster on repositories with many 3960 branches/tags. 3961 3962 .. versionadded:: 2019.2.0 3963 3964 heads : False 3965 Restrict output to heads. Can be combined with ``tags``. 3966 3967 tags : False 3968 Restrict output to tags. Can be combined with ``heads``. 3969 3970 user 3971 User under which to run the git command. By default, the command is run 3972 by the user under which the minion is running. 3973 3974 password 3975 Windows only. Required when specifying ``user``. This parameter will be 3976 ignored on non-Windows platforms. 3977 3978 .. versionadded:: 2016.3.4 3979 3980 identity 3981 Path to a private key to use for ssh URLs 3982 3983 .. warning:: 3984 3985 Unless Salt is invoked from the minion using ``salt-call``, the 3986 key(s) must be passphraseless. For greater security with 3987 passphraseless private keys, see the `sshd(8)`_ manpage for 3988 information on securing the keypair from the remote side in the 3989 ``authorized_keys`` file. 3990 3991 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 3992 3993 .. versionchanged:: 2015.8.7 3994 3995 Salt will no longer attempt to use passphrase-protected keys unless 3996 invoked from the minion using ``salt-call``, to prevent blocking 3997 waiting for user input. 3998 3999 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 4000 4001 .. versionchanged:: 2016.3.0 4002 4003 https_user 4004 Set HTTP Basic Auth username. Only accepted for HTTPS URLs. 4005 4006 https_pass 4007 Set HTTP Basic Auth password. Only accepted for HTTPS URLs. 4008 4009 ignore_retcode : False 4010 If ``True``, do not log an error to the minion log if the git command 4011 returns a nonzero exit status. 4012 4013 saltenv 4014 The default salt environment to pull sls files from 4015 4016 .. versionadded:: 2016.3.1 4017 4018 output_encoding 4019 Use this option to specify which encoding to use to decode the output 4020 from any git commands which are run. This should not be needed in most 4021 cases. 4022 4023 .. note:: 4024 This should only be needed if the files in the repository were 4025 created with filenames using an encoding other than UTF-8 to handle 4026 Unicode characters. 4027 4028 .. versionadded:: 2018.3.1 4029 4030 CLI Example: 4031 4032 .. code-block:: bash 4033 4034 salt myminion git.remote_refs https://github.com/saltstack/salt.git 4035 salt myminion git.remote_refs https://github.com/saltstack/salt.git filter=develop 4036 """ 4037 kwargs = salt.utils.args.clean_kwargs(**kwargs) 4038 filter_ = kwargs.pop("filter", None) 4039 if kwargs: 4040 salt.utils.args.invalid_kwargs(kwargs) 4041 4042 command = ["git", "ls-remote"] 4043 if heads: 4044 command.append("--heads") 4045 if tags: 4046 command.append("--tags") 4047 try: 4048 command.append( 4049 salt.utils.url.add_http_basic_auth( 4050 url, https_user, https_pass, https_only=True 4051 ) 4052 ) 4053 except ValueError as exc: 4054 raise SaltInvocationError(exc.__str__()) 4055 if filter_: 4056 command.append(filter_) 4057 output = _git_run( 4058 command, 4059 user=user, 4060 password=password, 4061 identity=identity, 4062 ignore_retcode=ignore_retcode, 4063 saltenv=saltenv, 4064 output_encoding=output_encoding, 4065 )["stdout"] 4066 ret = {} 4067 for line in salt.utils.itertools.split(output, "\n"): 4068 try: 4069 sha1_hash, ref_name = line.split(None, 1) 4070 except ValueError: 4071 continue 4072 ret[ref_name] = sha1_hash 4073 return ret 4074 4075 4076def remote_set( 4077 cwd, 4078 url, 4079 remote="origin", 4080 user=None, 4081 password=None, 4082 https_user=None, 4083 https_pass=None, 4084 push_url=None, 4085 push_https_user=None, 4086 push_https_pass=None, 4087 ignore_retcode=False, 4088 output_encoding=None, 4089): 4090 """ 4091 cwd 4092 The path to the git checkout 4093 4094 url 4095 Remote URL to set 4096 4097 remote : origin 4098 Name of the remote to set 4099 4100 push_url 4101 If unset, the push URL will be identical to the fetch URL. 4102 4103 .. versionadded:: 2015.8.0 4104 4105 user 4106 User under which to run the git command. By default, the command is run 4107 by the user under which the minion is running. 4108 4109 password 4110 Windows only. Required when specifying ``user``. This parameter will be 4111 ignored on non-Windows platforms. 4112 4113 .. versionadded:: 2016.3.4 4114 4115 https_user 4116 Set HTTP Basic Auth username. Only accepted for HTTPS URLs. 4117 4118 .. versionadded:: 2015.5.0 4119 4120 https_pass 4121 Set HTTP Basic Auth password. Only accepted for HTTPS URLs. 4122 4123 .. versionadded:: 2015.5.0 4124 4125 push_https_user 4126 Set HTTP Basic Auth user for ``push_url``. Ignored if ``push_url`` is 4127 unset. Only accepted for HTTPS URLs. 4128 4129 .. versionadded:: 2015.8.0 4130 4131 push_https_pass 4132 Set HTTP Basic Auth password for ``push_url``. Ignored if ``push_url`` 4133 is unset. Only accepted for HTTPS URLs. 4134 4135 .. versionadded:: 2015.8.0 4136 4137 ignore_retcode : False 4138 If ``True``, do not log an error to the minion log if the git command 4139 returns a nonzero exit status. 4140 4141 .. versionadded:: 2015.8.0 4142 4143 output_encoding 4144 Use this option to specify which encoding to use to decode the output 4145 from any git commands which are run. This should not be needed in most 4146 cases. 4147 4148 .. note:: 4149 This should only be needed if the files in the repository were 4150 created with filenames using an encoding other than UTF-8 to handle 4151 Unicode characters. 4152 4153 .. versionadded:: 2018.3.1 4154 4155 CLI Examples: 4156 4157 .. code-block:: bash 4158 4159 salt myminion git.remote_set /path/to/repo git@github.com:user/repo.git 4160 salt myminion git.remote_set /path/to/repo git@github.com:user/repo.git remote=upstream 4161 salt myminion git.remote_set /path/to/repo https://github.com/user/repo.git remote=upstream push_url=git@github.com:user/repo.git 4162 """ 4163 # Check if remote exists 4164 if remote in remotes( 4165 cwd, user=user, password=password, output_encoding=output_encoding 4166 ): 4167 log.debug( 4168 "Remote '%s' already exists in git checkout located at %s, " 4169 "removing so it can be re-added", 4170 remote, 4171 cwd, 4172 ) 4173 command = ["git", "remote", "rm", remote] 4174 _git_run( 4175 command, 4176 cwd=cwd, 4177 user=user, 4178 password=password, 4179 ignore_retcode=ignore_retcode, 4180 output_encoding=output_encoding, 4181 ) 4182 # Add remote 4183 try: 4184 url = salt.utils.url.add_http_basic_auth( 4185 url, https_user, https_pass, https_only=True 4186 ) 4187 except ValueError as exc: 4188 raise SaltInvocationError(exc.__str__()) 4189 command = ["git", "remote", "add", remote, url] 4190 _git_run( 4191 command, 4192 cwd=cwd, 4193 user=user, 4194 password=password, 4195 ignore_retcode=ignore_retcode, 4196 output_encoding=output_encoding, 4197 ) 4198 if push_url: 4199 if not isinstance(push_url, str): 4200 push_url = str(push_url) 4201 try: 4202 push_url = salt.utils.url.add_http_basic_auth( 4203 push_url, push_https_user, push_https_pass, https_only=True 4204 ) 4205 except ValueError as exc: 4206 raise SaltInvocationError(str(exc)) 4207 command = ["git", "remote", "set-url", "--push", remote, push_url] 4208 _git_run( 4209 command, 4210 cwd=cwd, 4211 user=user, 4212 password=password, 4213 ignore_retcode=ignore_retcode, 4214 output_encoding=output_encoding, 4215 ) 4216 return remote_get( 4217 cwd=cwd, 4218 remote=remote, 4219 user=user, 4220 password=password, 4221 ignore_retcode=ignore_retcode, 4222 output_encoding=output_encoding, 4223 ) 4224 4225 4226def remotes( 4227 cwd, 4228 user=None, 4229 password=None, 4230 redact_auth=True, 4231 ignore_retcode=False, 4232 output_encoding=None, 4233): 4234 """ 4235 Get fetch and push URLs for each remote in a git checkout 4236 4237 cwd 4238 The path to the git checkout 4239 4240 user 4241 User under which to run the git command. By default, the command is run 4242 by the user under which the minion is running. 4243 4244 password 4245 Windows only. Required when specifying ``user``. This parameter will be 4246 ignored on non-Windows platforms. 4247 4248 .. versionadded:: 2016.3.4 4249 4250 redact_auth : True 4251 Set to ``False`` to include the username/password for authenticated 4252 remotes in the return data. Otherwise, this information will be 4253 redacted. 4254 4255 .. warning:: 4256 Setting this to ``False`` will not only reveal any HTTPS Basic Auth 4257 that is configured, but the return data will also be written to the 4258 job cache. When possible, it is recommended to use SSH for 4259 authentication. 4260 4261 .. versionadded:: 2015.5.6 4262 4263 ignore_retcode : False 4264 If ``True``, do not log an error to the minion log if the git command 4265 returns a nonzero exit status. 4266 4267 .. versionadded:: 2015.8.0 4268 4269 output_encoding 4270 Use this option to specify which encoding to use to decode the output 4271 from any git commands which are run. This should not be needed in most 4272 cases. 4273 4274 .. note:: 4275 This should only be needed if the files in the repository were 4276 created with filenames using an encoding other than UTF-8 to handle 4277 Unicode characters. 4278 4279 .. versionadded:: 2018.3.1 4280 4281 CLI Example: 4282 4283 .. code-block:: bash 4284 4285 salt myminion git.remotes /path/to/repo 4286 """ 4287 cwd = _expand_path(cwd, user) 4288 command = ["git", "remote", "--verbose"] 4289 ret = {} 4290 output = _git_run( 4291 command, 4292 cwd=cwd, 4293 user=user, 4294 password=password, 4295 ignore_retcode=ignore_retcode, 4296 output_encoding=output_encoding, 4297 )["stdout"] 4298 for remote_line in salt.utils.itertools.split(output, "\n"): 4299 try: 4300 remote, remote_info = remote_line.split(None, 1) 4301 except ValueError: 4302 continue 4303 try: 4304 remote_url, action = remote_info.rsplit(None, 1) 4305 except ValueError: 4306 continue 4307 # Remove parenthesis 4308 action = action.lstrip("(").rstrip(")").lower() 4309 if action not in ("fetch", "push"): 4310 log.warning( 4311 "Unknown action '%s' for remote '%s' in git checkout located in %s", 4312 action, 4313 remote, 4314 cwd, 4315 ) 4316 continue 4317 if redact_auth: 4318 remote_url = salt.utils.url.redact_http_basic_auth(remote_url) 4319 ret.setdefault(remote, {})[action] = remote_url 4320 return ret 4321 4322 4323def reset( 4324 cwd, 4325 opts="", 4326 git_opts="", 4327 user=None, 4328 password=None, 4329 identity=None, 4330 ignore_retcode=False, 4331 output_encoding=None, 4332): 4333 """ 4334 Interface to `git-reset(1)`_, returns the stdout from the git command 4335 4336 cwd 4337 The path to the git checkout 4338 4339 opts 4340 Any additional options to add to the command line, in a single string 4341 4342 .. note:: 4343 On the Salt CLI, if the opts are preceded with a dash, it is 4344 necessary to precede them with ``opts=`` (as in the CLI examples 4345 below) to avoid causing errors with Salt's own argument parsing. 4346 4347 git_opts 4348 Any additional options to add to git command itself (not the ``reset`` 4349 subcommand), in a single string. This is useful for passing ``-c`` to 4350 run git with temporary changes to the git configuration. 4351 4352 .. versionadded:: 2017.7.0 4353 4354 .. note:: 4355 This is only supported in git 1.7.2 and newer. 4356 4357 user 4358 User under which to run the git command. By default, the command is run 4359 by the user under which the minion is running. 4360 4361 password 4362 Windows only. Required when specifying ``user``. This parameter will be 4363 ignored on non-Windows platforms. 4364 4365 .. versionadded:: 2016.3.4 4366 4367 identity 4368 Path to a private key to use for ssh URLs. Salt will not attempt to use 4369 passphrase-protected keys unless invoked from the minion using 4370 ``salt-call``, to prevent blocking waiting for user input. Key can also 4371 be specified as a SaltStack file server URL, eg. 4372 ``salt://location/identity_file``. 4373 4374 .. note:: 4375 For greater security with passphraseless private keys, see the 4376 `sshd(8)`_ manpage for information on securing the keypair from the 4377 remote side in the ``authorized_keys`` file. 4378 4379 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 4380 4381 .. versionadded:: 2018.3.5,2019.2.1,3000 4382 4383 ignore_retcode : False 4384 If ``True``, do not log an error to the minion log if the git command 4385 returns a nonzero exit status. 4386 4387 .. versionadded:: 2015.8.0 4388 4389 output_encoding 4390 Use this option to specify which encoding to use to decode the output 4391 from any git commands which are run. This should not be needed in most 4392 cases. 4393 4394 .. note:: 4395 This should only be needed if the files in the repository were 4396 created with filenames using an encoding other than UTF-8 to handle 4397 Unicode characters. 4398 4399 .. versionadded:: 2018.3.1 4400 4401 .. _`git-reset(1)`: http://git-scm.com/docs/git-reset 4402 4403 CLI Examples: 4404 4405 .. code-block:: bash 4406 4407 # Soft reset to a specific commit ID 4408 salt myminion git.reset /path/to/repo ac3ee5c 4409 # Hard reset 4410 salt myminion git.reset /path/to/repo opts='--hard origin/master' 4411 """ 4412 cwd = _expand_path(cwd, user) 4413 command = ["git"] + _format_git_opts(git_opts) 4414 command.append("reset") 4415 command.extend(_format_opts(opts)) 4416 return _git_run( 4417 command, 4418 cwd=cwd, 4419 user=user, 4420 password=password, 4421 identity=identity, 4422 ignore_retcode=ignore_retcode, 4423 output_encoding=output_encoding, 4424 )["stdout"] 4425 4426 4427def rev_parse( 4428 cwd, 4429 rev=None, 4430 opts="", 4431 git_opts="", 4432 user=None, 4433 password=None, 4434 ignore_retcode=False, 4435 output_encoding=None, 4436): 4437 """ 4438 .. versionadded:: 2015.8.0 4439 4440 Interface to `git-rev-parse(1)`_ 4441 4442 cwd 4443 The path to the git checkout 4444 4445 rev 4446 Revision to parse. See the `SPECIFYING REVISIONS`_ section of the 4447 `git-rev-parse(1)`_ manpage for details on how to format this argument. 4448 4449 This argument is optional when using the options in the `Options for 4450 Files` section of the `git-rev-parse(1)`_ manpage. 4451 4452 opts 4453 Any additional options to add to the command line, in a single string 4454 4455 git_opts 4456 Any additional options to add to git command itself (not the 4457 ``rev-parse`` subcommand), in a single string. This is useful for 4458 passing ``-c`` to run git with temporary changes to the git 4459 configuration. 4460 4461 .. versionadded:: 2017.7.0 4462 4463 .. note:: 4464 This is only supported in git 1.7.2 and newer. 4465 4466 user 4467 User under which to run the git command. By default, the command is run 4468 by the user under which the minion is running. 4469 4470 password 4471 Windows only. Required when specifying ``user``. This parameter will be 4472 ignored on non-Windows platforms. 4473 4474 .. versionadded:: 2016.3.4 4475 4476 ignore_retcode : False 4477 If ``True``, do not log an error to the minion log if the git command 4478 returns a nonzero exit status. 4479 4480 output_encoding 4481 Use this option to specify which encoding to use to decode the output 4482 from any git commands which are run. This should not be needed in most 4483 cases. 4484 4485 .. note:: 4486 This should only be needed if the files in the repository were 4487 created with filenames using an encoding other than UTF-8 to handle 4488 Unicode characters. 4489 4490 .. versionadded:: 2018.3.1 4491 4492 .. _`git-rev-parse(1)`: http://git-scm.com/docs/git-rev-parse 4493 .. _`SPECIFYING REVISIONS`: http://git-scm.com/docs/git-rev-parse#_specifying_revisions 4494 .. _`Options for Files`: http://git-scm.com/docs/git-rev-parse#_options_for_files 4495 4496 CLI Examples: 4497 4498 .. code-block:: bash 4499 4500 # Get the full SHA1 for HEAD 4501 salt myminion git.rev_parse /path/to/repo HEAD 4502 # Get the short SHA1 for HEAD 4503 salt myminion git.rev_parse /path/to/repo HEAD opts='--short' 4504 # Get the develop branch's upstream tracking branch 4505 salt myminion git.rev_parse /path/to/repo 'develop@{upstream}' opts='--abbrev-ref' 4506 # Get the SHA1 for the commit corresponding to tag v1.2.3 4507 salt myminion git.rev_parse /path/to/repo 'v1.2.3^{commit}' 4508 # Find out whether or not the repo at /path/to/repo is a bare repository 4509 salt myminion git.rev_parse /path/to/repo opts='--is-bare-repository' 4510 """ 4511 cwd = _expand_path(cwd, user) 4512 command = ["git"] + _format_git_opts(git_opts) 4513 command.append("rev-parse") 4514 command.extend(_format_opts(opts)) 4515 if rev is not None: 4516 command.append(rev) 4517 return _git_run( 4518 command, 4519 cwd=cwd, 4520 user=user, 4521 password=password, 4522 ignore_retcode=ignore_retcode, 4523 output_encoding=output_encoding, 4524 )["stdout"] 4525 4526 4527def revision( 4528 cwd, 4529 rev="HEAD", 4530 short=False, 4531 user=None, 4532 password=None, 4533 ignore_retcode=False, 4534 output_encoding=None, 4535): 4536 """ 4537 Returns the SHA1 hash of a given identifier (hash, branch, tag, HEAD, etc.) 4538 4539 cwd 4540 The path to the git checkout 4541 4542 rev : HEAD 4543 The revision 4544 4545 short : False 4546 If ``True``, return an abbreviated SHA1 git hash 4547 4548 user 4549 User under which to run the git command. By default, the command is run 4550 by the user under which the minion is running. 4551 4552 password 4553 Windows only. Required when specifying ``user``. This parameter will be 4554 ignored on non-Windows platforms. 4555 4556 .. versionadded:: 2016.3.4 4557 4558 ignore_retcode : False 4559 If ``True``, do not log an error to the minion log if the git command 4560 returns a nonzero exit status. 4561 4562 .. versionadded:: 2015.8.0 4563 4564 output_encoding 4565 Use this option to specify which encoding to use to decode the output 4566 from any git commands which are run. This should not be needed in most 4567 cases. 4568 4569 .. note:: 4570 This should only be needed if the files in the repository were 4571 created with filenames using an encoding other than UTF-8 to handle 4572 Unicode characters. 4573 4574 .. versionadded:: 2018.3.1 4575 4576 CLI Example: 4577 4578 .. code-block:: bash 4579 4580 salt myminion git.revision /path/to/repo mybranch 4581 """ 4582 cwd = _expand_path(cwd, user) 4583 command = ["git", "rev-parse"] 4584 if short: 4585 command.append("--short") 4586 command.append(rev) 4587 return _git_run( 4588 command, 4589 cwd=cwd, 4590 user=user, 4591 password=password, 4592 ignore_retcode=ignore_retcode, 4593 output_encoding=output_encoding, 4594 )["stdout"] 4595 4596 4597def rm_( 4598 cwd, 4599 filename, 4600 opts="", 4601 git_opts="", 4602 user=None, 4603 password=None, 4604 ignore_retcode=False, 4605 output_encoding=None, 4606): 4607 """ 4608 Interface to `git-rm(1)`_ 4609 4610 cwd 4611 The path to the git checkout 4612 4613 filename 4614 The location of the file/directory to remove, relative to ``cwd`` 4615 4616 .. note:: 4617 To remove a directory, ``-r`` must be part of the ``opts`` 4618 parameter. 4619 4620 opts 4621 Any additional options to add to the command line, in a single string 4622 4623 .. note:: 4624 On the Salt CLI, if the opts are preceded with a dash, it is 4625 necessary to precede them with ``opts=`` (as in the CLI examples 4626 below) to avoid causing errors with Salt's own argument parsing. 4627 4628 git_opts 4629 Any additional options to add to git command itself (not the ``rm`` 4630 subcommand), in a single string. This is useful for passing ``-c`` to 4631 run git with temporary changes to the git configuration. 4632 4633 .. versionadded:: 2017.7.0 4634 4635 .. note:: 4636 This is only supported in git 1.7.2 and newer. 4637 4638 user 4639 User under which to run the git command. By default, the command is run 4640 by the user under which the minion is running. 4641 4642 password 4643 Windows only. Required when specifying ``user``. This parameter will be 4644 ignored on non-Windows platforms. 4645 4646 .. versionadded:: 2016.3.4 4647 4648 ignore_retcode : False 4649 If ``True``, do not log an error to the minion log if the git command 4650 returns a nonzero exit status. 4651 4652 .. versionadded:: 2015.8.0 4653 4654 output_encoding 4655 Use this option to specify which encoding to use to decode the output 4656 from any git commands which are run. This should not be needed in most 4657 cases. 4658 4659 .. note:: 4660 This should only be needed if the files in the repository were 4661 created with filenames using an encoding other than UTF-8 to handle 4662 Unicode characters. 4663 4664 .. versionadded:: 2018.3.1 4665 4666 .. _`git-rm(1)`: http://git-scm.com/docs/git-rm 4667 4668 CLI Examples: 4669 4670 .. code-block:: bash 4671 4672 salt myminion git.rm /path/to/repo foo/bar.py 4673 salt myminion git.rm /path/to/repo foo/bar.py opts='--dry-run' 4674 salt myminion git.rm /path/to/repo foo/baz opts='-r' 4675 """ 4676 cwd = _expand_path(cwd, user) 4677 command = ["git"] + _format_git_opts(git_opts) 4678 command.append("rm") 4679 command.extend(_format_opts(opts)) 4680 command.extend(["--", filename]) 4681 return _git_run( 4682 command, 4683 cwd=cwd, 4684 user=user, 4685 password=password, 4686 ignore_retcode=ignore_retcode, 4687 output_encoding=output_encoding, 4688 )["stdout"] 4689 4690 4691def stash( 4692 cwd, 4693 action="save", 4694 opts="", 4695 git_opts="", 4696 user=None, 4697 password=None, 4698 ignore_retcode=False, 4699 output_encoding=None, 4700): 4701 """ 4702 Interface to `git-stash(1)`_, returns the stdout from the git command 4703 4704 cwd 4705 The path to the git checkout 4706 4707 opts 4708 Any additional options to add to the command line, in a single string. 4709 Use this to complete the ``git stash`` command by adding the remaining 4710 arguments (i.e. ``'save <stash comment>'``, ``'apply stash@{2}'``, 4711 ``'show'``, etc.). Omitting this argument will simply run ``git 4712 stash``. 4713 4714 git_opts 4715 Any additional options to add to git command itself (not the ``stash`` 4716 subcommand), in a single string. This is useful for passing ``-c`` to 4717 run git with temporary changes to the git configuration. 4718 4719 .. versionadded:: 2017.7.0 4720 4721 .. note:: 4722 This is only supported in git 1.7.2 and newer. 4723 4724 user 4725 User under which to run the git command. By default, the command is run 4726 by the user under which the minion is running. 4727 4728 password 4729 Windows only. Required when specifying ``user``. This parameter will be 4730 ignored on non-Windows platforms. 4731 4732 .. versionadded:: 2016.3.4 4733 4734 ignore_retcode : False 4735 If ``True``, do not log an error to the minion log if the git command 4736 returns a nonzero exit status. 4737 4738 .. versionadded:: 2015.8.0 4739 4740 output_encoding 4741 Use this option to specify which encoding to use to decode the output 4742 from any git commands which are run. This should not be needed in most 4743 cases. 4744 4745 .. note:: 4746 This should only be needed if the files in the repository were 4747 created with filenames using an encoding other than UTF-8 to handle 4748 Unicode characters. 4749 4750 .. versionadded:: 2018.3.1 4751 4752 .. _`git-stash(1)`: http://git-scm.com/docs/git-stash 4753 4754 CLI Examples: 4755 4756 .. code-block:: bash 4757 4758 salt myminion git.stash /path/to/repo save opts='work in progress' 4759 salt myminion git.stash /path/to/repo apply opts='stash@{1}' 4760 salt myminion git.stash /path/to/repo drop opts='stash@{1}' 4761 salt myminion git.stash /path/to/repo list 4762 """ 4763 cwd = _expand_path(cwd, user) 4764 command = ["git"] + _format_git_opts(git_opts) 4765 command.extend(["stash", action]) 4766 command.extend(_format_opts(opts)) 4767 return _git_run( 4768 command, 4769 cwd=cwd, 4770 user=user, 4771 password=password, 4772 ignore_retcode=ignore_retcode, 4773 output_encoding=output_encoding, 4774 )["stdout"] 4775 4776 4777def status(cwd, user=None, password=None, ignore_retcode=False, output_encoding=None): 4778 """ 4779 .. versionchanged:: 2015.8.0 4780 Return data has changed from a list of lists to a dictionary 4781 4782 Returns the changes to the repository 4783 4784 cwd 4785 The path to the git checkout 4786 4787 user 4788 User under which to run the git command. By default, the command is run 4789 by the user under which the minion is running. 4790 4791 password 4792 Windows only. Required when specifying ``user``. This parameter will be 4793 ignored on non-Windows platforms. 4794 4795 .. versionadded:: 2016.3.4 4796 4797 ignore_retcode : False 4798 If ``True``, do not log an error to the minion log if the git command 4799 returns a nonzero exit status. 4800 4801 .. versionadded:: 2015.8.0 4802 4803 output_encoding 4804 Use this option to specify which encoding to use to decode the output 4805 from any git commands which are run. This should not be needed in most 4806 cases. 4807 4808 .. note:: 4809 This should only be needed if the files in the repository were 4810 created with filenames using an encoding other than UTF-8 to handle 4811 Unicode characters. 4812 4813 .. versionadded:: 2018.3.1 4814 4815 CLI Example: 4816 4817 .. code-block:: bash 4818 4819 salt myminion git.status /path/to/repo 4820 """ 4821 cwd = _expand_path(cwd, user) 4822 state_map = {"M": "modified", "A": "new", "D": "deleted", "??": "untracked"} 4823 ret = {} 4824 command = ["git", "status", "-z", "--porcelain"] 4825 output = _git_run( 4826 command, 4827 cwd=cwd, 4828 user=user, 4829 password=password, 4830 ignore_retcode=ignore_retcode, 4831 output_encoding=output_encoding, 4832 )["stdout"] 4833 for line in output.split("\0"): 4834 try: 4835 state, filename = line.split(None, 1) 4836 except ValueError: 4837 continue 4838 ret.setdefault(state_map.get(state, state), []).append(filename) 4839 return ret 4840 4841 4842def submodule( 4843 cwd, 4844 command, 4845 opts="", 4846 git_opts="", 4847 user=None, 4848 password=None, 4849 identity=None, 4850 ignore_retcode=False, 4851 saltenv="base", 4852 output_encoding=None, 4853 **kwargs 4854): 4855 """ 4856 .. versionchanged:: 2015.8.0 4857 Added the ``command`` argument to allow for operations other than 4858 ``update`` to be run on submodules, and deprecated the ``init`` 4859 argument. To do a submodule update with ``init=True`` moving forward, 4860 use ``command=update opts='--init'`` 4861 4862 Interface to `git-submodule(1)`_ 4863 4864 cwd 4865 The path to the submodule 4866 4867 command 4868 Submodule command to run, see `git-submodule(1) <git submodule>` for 4869 more information. Any additional arguments after the command (such as 4870 the URL when adding a submodule) must be passed in the ``opts`` 4871 parameter. 4872 4873 .. versionadded:: 2015.8.0 4874 4875 opts 4876 Any additional options to add to the command line, in a single string 4877 4878 .. note:: 4879 On the Salt CLI, if the opts are preceded with a dash, it is 4880 necessary to precede them with ``opts=`` (as in the CLI examples 4881 below) to avoid causing errors with Salt's own argument parsing. 4882 4883 git_opts 4884 Any additional options to add to git command itself (not the 4885 ``submodule`` subcommand), in a single string. This is useful for 4886 passing ``-c`` to run git with temporary changes to the git 4887 configuration. 4888 4889 .. versionadded:: 2017.7.0 4890 4891 .. note:: 4892 This is only supported in git 1.7.2 and newer. 4893 4894 init : False 4895 If ``True``, ensures that new submodules are initialized 4896 4897 .. deprecated:: 2015.8.0 4898 Pass ``init`` as the ``command`` parameter, or include ``--init`` 4899 in the ``opts`` param with ``command`` set to update. 4900 4901 user 4902 User under which to run the git command. By default, the command is run 4903 by the user under which the minion is running. 4904 4905 password 4906 Windows only. Required when specifying ``user``. This parameter will be 4907 ignored on non-Windows platforms. 4908 4909 .. versionadded:: 2016.3.4 4910 4911 identity 4912 Path to a private key to use for ssh URLs 4913 4914 .. warning:: 4915 4916 Unless Salt is invoked from the minion using ``salt-call``, the 4917 key(s) must be passphraseless. For greater security with 4918 passphraseless private keys, see the `sshd(8)`_ manpage for 4919 information on securing the keypair from the remote side in the 4920 ``authorized_keys`` file. 4921 4922 .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT 4923 4924 .. versionchanged:: 2015.8.7 4925 4926 Salt will no longer attempt to use passphrase-protected keys unless 4927 invoked from the minion using ``salt-call``, to prevent blocking 4928 waiting for user input. 4929 4930 Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file 4931 4932 .. versionchanged:: 2016.3.0 4933 4934 ignore_retcode : False 4935 If ``True``, do not log an error to the minion log if the git command 4936 returns a nonzero exit status. 4937 4938 .. versionadded:: 2015.8.0 4939 4940 saltenv 4941 The default salt environment to pull sls files from 4942 4943 .. versionadded:: 2016.3.1 4944 4945 output_encoding 4946 Use this option to specify which encoding to use to decode the output 4947 from any git commands which are run. This should not be needed in most 4948 cases. 4949 4950 .. note:: 4951 This should only be needed if the files in the repository were 4952 created with filenames using an encoding other than UTF-8 to handle 4953 Unicode characters. 4954 4955 .. versionadded:: 2018.3.1 4956 4957 .. _`git-submodule(1)`: http://git-scm.com/docs/git-submodule 4958 4959 CLI Example: 4960 4961 .. code-block:: bash 4962 4963 # Update submodule and ensure it is initialized (before 2015.8.0) 4964 salt myminion git.submodule /path/to/repo/sub/repo init=True 4965 # Update submodule and ensure it is initialized (2015.8.0 and later) 4966 salt myminion git.submodule /path/to/repo/sub/repo update opts='--init' 4967 4968 # Rebase submodule (2015.8.0 and later) 4969 salt myminion git.submodule /path/to/repo/sub/repo update opts='--rebase' 4970 4971 # Add submodule (2015.8.0 and later) 4972 salt myminion git.submodule /path/to/repo/sub/repo add opts='https://mydomain.tld/repo.git' 4973 4974 # Unregister submodule (2015.8.0 and later) 4975 salt myminion git.submodule /path/to/repo/sub/repo deinit 4976 """ 4977 kwargs = salt.utils.args.clean_kwargs(**kwargs) 4978 init_ = kwargs.pop("init", False) 4979 if kwargs: 4980 salt.utils.args.invalid_kwargs(kwargs) 4981 4982 cwd = _expand_path(cwd, user) 4983 if init_: 4984 raise SaltInvocationError( 4985 "The 'init' argument is no longer supported. Either set " 4986 "'command' to 'init', or include '--init' in the 'opts' " 4987 "argument and set 'command' to 'update'." 4988 ) 4989 cmd = ["git"] + _format_git_opts(git_opts) 4990 cmd.extend(["submodule", command]) 4991 cmd.extend(_format_opts(opts)) 4992 return _git_run( 4993 cmd, 4994 cwd=cwd, 4995 user=user, 4996 password=password, 4997 identity=identity, 4998 ignore_retcode=ignore_retcode, 4999 saltenv=saltenv, 5000 output_encoding=output_encoding, 5001 )["stdout"] 5002 5003 5004def symbolic_ref( 5005 cwd, 5006 ref, 5007 value=None, 5008 opts="", 5009 git_opts="", 5010 user=None, 5011 password=None, 5012 ignore_retcode=False, 5013 output_encoding=None, 5014): 5015 """ 5016 .. versionadded:: 2015.8.0 5017 5018 Interface to `git-symbolic-ref(1)`_ 5019 5020 cwd 5021 The path to the git checkout 5022 5023 ref 5024 Symbolic ref to read/modify 5025 5026 value 5027 If passed, then the symbolic ref will be set to this value and an empty 5028 string will be returned. 5029 5030 If not passed, then the ref to which ``ref`` points will be returned, 5031 unless ``--delete`` is included in ``opts`` (in which case the symbolic 5032 ref will be deleted). 5033 5034 opts 5035 Any additional options to add to the command line, in a single string 5036 5037 git_opts 5038 Any additional options to add to git command itself (not the 5039 ``symbolic-refs`` subcommand), in a single string. This is useful for 5040 passing ``-c`` to run git with temporary changes to the git 5041 configuration. 5042 5043 .. versionadded:: 2017.7.0 5044 5045 .. note:: 5046 This is only supported in git 1.7.2 and newer. 5047 5048 user 5049 User under which to run the git command. By default, the command is run 5050 by the user under which the minion is running. 5051 5052 password 5053 Windows only. Required when specifying ``user``. This parameter will be 5054 ignored on non-Windows platforms. 5055 5056 .. versionadded:: 2016.3.4 5057 5058 ignore_retcode : False 5059 If ``True``, do not log an error to the minion log if the git command 5060 returns a nonzero exit status. 5061 5062 .. versionadded:: 2015.8.0 5063 5064 output_encoding 5065 Use this option to specify which encoding to use to decode the output 5066 from any git commands which are run. This should not be needed in most 5067 cases. 5068 5069 .. note:: 5070 This should only be needed if the files in the repository were 5071 created with filenames using an encoding other than UTF-8 to handle 5072 Unicode characters. 5073 5074 .. versionadded:: 2018.3.1 5075 5076 .. _`git-symbolic-ref(1)`: http://git-scm.com/docs/git-symbolic-ref 5077 5078 CLI Examples: 5079 5080 .. code-block:: bash 5081 5082 # Get ref to which HEAD is pointing 5083 salt myminion git.symbolic_ref /path/to/repo HEAD 5084 # Set/overwrite symbolic ref 'FOO' to local branch 'foo' 5085 salt myminion git.symbolic_ref /path/to/repo FOO refs/heads/foo 5086 # Delete symbolic ref 'FOO' 5087 salt myminion git.symbolic_ref /path/to/repo FOO opts='--delete' 5088 """ 5089 cwd = _expand_path(cwd, user) 5090 command = ["git"] + _format_git_opts(git_opts) 5091 command.append("symbolic-ref") 5092 opts = _format_opts(opts) 5093 if value is not None and any(x in opts for x in ("-d", "--delete")): 5094 raise SaltInvocationError( 5095 "Value cannot be set for symbolic ref if -d/--delete is included in opts" 5096 ) 5097 command.extend(opts) 5098 command.append(ref) 5099 if value: 5100 command.extend(value) 5101 return _git_run( 5102 command, 5103 cwd=cwd, 5104 user=user, 5105 password=password, 5106 ignore_retcode=ignore_retcode, 5107 output_encoding=output_encoding, 5108 )["stdout"] 5109 5110 5111def tag( 5112 cwd, 5113 name, 5114 ref="HEAD", 5115 message=None, 5116 opts="", 5117 git_opts="", 5118 user=None, 5119 password=None, 5120 ignore_retcode=False, 5121 output_encoding=None, 5122): 5123 """ 5124 .. versionadded:: 2018.3.4 5125 5126 Interface to `git-tag(1)`_, adds and removes tags. 5127 5128 cwd 5129 The path to the main git checkout or a linked worktree 5130 5131 name 5132 Name of the tag 5133 5134 ref : HEAD 5135 Which ref to tag (defaults to local clone's HEAD) 5136 5137 .. note:: 5138 This argument is ignored when either ``-d`` or ``--delete`` is 5139 present in the ``opts`` passed to this function. 5140 5141 message 5142 Optional message to include with the tag. If provided, an annotated tag 5143 will be created. 5144 5145 opts 5146 Any additional options to add to the command line, in a single string 5147 5148 .. note:: 5149 Additionally, on the Salt CLI, if the opts are preceded with a 5150 dash, it is necessary to precede them with ``opts=`` (as in the CLI 5151 examples below) to avoid causing errors with Salt's own argument 5152 parsing. 5153 5154 git_opts 5155 Any additional options to add to git command itself (not the 5156 ``worktree`` subcommand), in a single string. This is useful for 5157 passing ``-c`` to run git with temporary changes to the git 5158 configuration. 5159 5160 .. note:: 5161 This is only supported in git 1.7.2 and newer. 5162 5163 user 5164 User under which to run the git command. By default, the command is run 5165 by the user under which the minion is running. 5166 5167 password 5168 Windows only. Required when specifying ``user``. This parameter will be 5169 ignored on non-Windows platforms. 5170 5171 ignore_retcode : False 5172 If ``True``, do not log an error to the minion log if the git command 5173 returns a nonzero exit status. 5174 5175 output_encoding 5176 Use this option to specify which encoding to use to decode the output 5177 from any git commands which are run. This should not be needed in most 5178 cases. 5179 5180 .. note:: 5181 This should only be needed if the files in the repository were 5182 created with filenames using an encoding other than UTF-8 to handle 5183 Unicode characters. 5184 5185 .. _`git-tag(1)`: http://git-scm.com/docs/git-tag 5186 5187 CLI Example: 5188 5189 .. code-block:: bash 5190 5191 # Create an non-annotated tag 5192 salt myminion git.tag /path/to/repo v1.2 5193 # Create an annotated tag 5194 salt myminion git.tag /path/to/repo v1.2 message='Version 1.2' 5195 # Delete the tag 5196 salt myminion git.tag /path/to/repo v1.2 opts='-d' 5197 """ 5198 cwd = _expand_path(cwd, user) 5199 command = ["git"] + _format_git_opts(git_opts) 5200 command.append("tag") 5201 # Don't add options for annotated tags, since we'll automatically add them 5202 # if a message was passed. This keeps us from blocking on input, as passing 5203 # these options without a separate message option would launch an editor. 5204 formatted_opts = [x for x in _format_opts(opts) if x not in ("-a", "--annotate")] 5205 # Make sure that the message was not passed in the opts 5206 if any(x == "-m" or "--message" in x for x in formatted_opts): 5207 raise SaltInvocationError( 5208 'Tag messages must be passed in the "message" argument' 5209 ) 5210 command.extend(formatted_opts) 5211 command.append(name) 5212 if "-d" not in formatted_opts and "--delete" not in formatted_opts: 5213 command.append(ref) 5214 return _git_run( 5215 command, 5216 cwd=cwd, 5217 user=user, 5218 password=password, 5219 ignore_retcode=ignore_retcode, 5220 redirect_stderr=True, 5221 output_encoding=output_encoding, 5222 )["stdout"] 5223 5224 5225def version(versioninfo=False): 5226 """ 5227 .. versionadded:: 2015.8.0 5228 5229 Returns the version of Git installed on the minion 5230 5231 versioninfo : False 5232 If ``True``, return the version in a versioninfo list (e.g. ``[2, 5, 5233 0]``) 5234 5235 CLI Example: 5236 5237 .. code-block:: bash 5238 5239 salt myminion git.version 5240 """ 5241 contextkey = "git.version" 5242 contextkey_info = "git.versioninfo" 5243 if contextkey not in __context__: 5244 try: 5245 version_ = _git_run(["git", "--version"])["stdout"] 5246 except CommandExecutionError as exc: 5247 log.error("Failed to obtain the git version (error follows):\n%s", exc) 5248 version_ = "unknown" 5249 try: 5250 __context__[contextkey] = version_.split()[-1] 5251 except IndexError: 5252 # Somehow git --version returned no stdout while not raising an 5253 # error. Should never happen but we should still account for this 5254 # possible edge case. 5255 log.error("Running 'git --version' returned no stdout") 5256 __context__[contextkey] = "unknown" 5257 if not versioninfo: 5258 return __context__[contextkey] 5259 if contextkey_info not in __context__: 5260 # Set ptr to the memory location of __context__[contextkey_info] to 5261 # prevent repeated dict lookups 5262 ptr = __context__.setdefault(contextkey_info, []) 5263 for part in __context__[contextkey].split("."): 5264 try: 5265 ptr.append(int(part)) 5266 except ValueError: 5267 ptr.append(part) 5268 return __context__[contextkey_info] 5269 5270 5271def worktree_add( 5272 cwd, 5273 worktree_path, 5274 ref=None, 5275 reset_branch=None, 5276 force=None, 5277 detach=False, 5278 opts="", 5279 git_opts="", 5280 user=None, 5281 password=None, 5282 ignore_retcode=False, 5283 output_encoding=None, 5284 **kwargs 5285): 5286 """ 5287 .. versionadded:: 2015.8.0 5288 5289 Interface to `git-worktree(1)`_, adds a worktree 5290 5291 cwd 5292 The path to the git checkout 5293 5294 worktree_path 5295 Path to the new worktree. Can be either absolute, or relative to 5296 ``cwd``. 5297 5298 branch 5299 Name of new branch to create. If omitted, will be set to the basename 5300 of the ``worktree_path``. For example, if the ``worktree_path`` is 5301 ``/foo/bar/baz``, then ``branch`` will be ``baz``. 5302 5303 ref 5304 Name of the ref on which to base the new worktree. If omitted, then 5305 ``HEAD`` is use, and a new branch will be created, named for the 5306 basename of the ``worktree_path``. For example, if the 5307 ``worktree_path`` is ``/foo/bar/baz`` then a new branch ``baz`` will be 5308 created, and pointed at ``HEAD``. 5309 5310 reset_branch : False 5311 If ``False``, then `git-worktree(1)`_ will fail to create the worktree 5312 if the targeted branch already exists. Set this argument to ``True`` to 5313 reset the targeted branch to point at ``ref``, and checkout the 5314 newly-reset branch into the new worktree. 5315 5316 force : False 5317 By default, `git-worktree(1)`_ will not permit the same branch to be 5318 checked out in more than one worktree. Set this argument to ``True`` to 5319 override this. 5320 5321 opts 5322 Any additional options to add to the command line, in a single string 5323 5324 .. note:: 5325 On the Salt CLI, if the opts are preceded with a dash, it is 5326 necessary to precede them with ``opts=`` to avoid causing errors 5327 with Salt's own argument parsing. 5328 5329 All CLI options for adding worktrees as of Git 2.5.0 are already 5330 supported by this function as of Salt 2015.8.0, so using this 5331 argument is unnecessary unless new CLI arguments are added to 5332 `git-worktree(1)`_ and are not yet supported in Salt. 5333 5334 git_opts 5335 Any additional options to add to git command itself (not the 5336 ``worktree`` subcommand), in a single string. This is useful for 5337 passing ``-c`` to run git with temporary changes to the git 5338 configuration. 5339 5340 .. versionadded:: 2017.7.0 5341 5342 .. note:: 5343 This is only supported in git 1.7.2 and newer. 5344 5345 user 5346 User under which to run the git command. By default, the command is run 5347 by the user under which the minion is running. 5348 5349 password 5350 Windows only. Required when specifying ``user``. This parameter will be 5351 ignored on non-Windows platforms. 5352 5353 .. versionadded:: 2016.3.4 5354 5355 ignore_retcode : False 5356 If ``True``, do not log an error to the minion log if the git command 5357 returns a nonzero exit status. 5358 5359 .. versionadded:: 2015.8.0 5360 5361 output_encoding 5362 Use this option to specify which encoding to use to decode the output 5363 from any git commands which are run. This should not be needed in most 5364 cases. 5365 5366 .. note:: 5367 This should only be needed if the files in the repository were 5368 created with filenames using an encoding other than UTF-8 to handle 5369 Unicode characters. 5370 5371 .. versionadded:: 2018.3.1 5372 5373 .. _`git-worktree(1)`: http://git-scm.com/docs/git-worktree 5374 5375 CLI Examples: 5376 5377 .. code-block:: bash 5378 5379 salt myminion git.worktree_add /path/to/repo/main ../hotfix ref=origin/master 5380 salt myminion git.worktree_add /path/to/repo/main ../hotfix branch=hotfix21 ref=v2.1.9.3 5381 """ 5382 _check_worktree_support() 5383 kwargs = salt.utils.args.clean_kwargs(**kwargs) 5384 branch_ = kwargs.pop("branch", None) 5385 if kwargs: 5386 salt.utils.args.invalid_kwargs(kwargs) 5387 5388 cwd = _expand_path(cwd, user) 5389 if branch_ and detach: 5390 raise SaltInvocationError("Only one of 'branch' and 'detach' is allowed") 5391 5392 command = ["git"] + _format_git_opts(git_opts) 5393 command.extend(["worktree", "add"]) 5394 if detach: 5395 if force: 5396 log.warning( 5397 "'force' argument to git.worktree_add is ignored when detach=True" 5398 ) 5399 command.append("--detach") 5400 else: 5401 if not branch_: 5402 branch_ = os.path.basename(worktree_path) 5403 command.extend(["-B" if reset_branch else "-b", branch_]) 5404 if force: 5405 command.append("--force") 5406 command.extend(_format_opts(opts)) 5407 command.append(worktree_path) 5408 if ref: 5409 command.append(ref) 5410 # Checkout message goes to stderr 5411 return _git_run( 5412 command, 5413 cwd=cwd, 5414 user=user, 5415 password=password, 5416 ignore_retcode=ignore_retcode, 5417 redirect_stderr=True, 5418 output_encoding=output_encoding, 5419 )["stdout"] 5420 5421 5422def worktree_prune( 5423 cwd, 5424 dry_run=False, 5425 verbose=True, 5426 expire=None, 5427 opts="", 5428 git_opts="", 5429 user=None, 5430 password=None, 5431 ignore_retcode=False, 5432 output_encoding=None, 5433): 5434 """ 5435 .. versionadded:: 2015.8.0 5436 5437 Interface to `git-worktree(1)`_, prunes stale worktree administrative data 5438 from the gitdir 5439 5440 cwd 5441 The path to the main git checkout or a linked worktree 5442 5443 dry_run : False 5444 If ``True``, then this function will report what would have been 5445 pruned, but no changes will be made. 5446 5447 verbose : True 5448 Report all changes made. Set to ``False`` to suppress this output. 5449 5450 expire 5451 Only prune unused worktree data older than a specific period of time. 5452 The date format for this parameter is described in the documentation 5453 for the ``gc.pruneWorktreesExpire`` config param in the 5454 `git-config(1)`_ manpage. 5455 5456 opts 5457 Any additional options to add to the command line, in a single string 5458 5459 .. note:: 5460 On the Salt CLI, if the opts are preceded with a dash, it is 5461 necessary to precede them with ``opts=`` to avoid causing errors 5462 with Salt's own argument parsing. 5463 5464 All CLI options for pruning worktrees as of Git 2.5.0 are already 5465 supported by this function as of Salt 2015.8.0, so using this 5466 argument is unnecessary unless new CLI arguments are added to 5467 `git-worktree(1)`_ and are not yet supported in Salt. 5468 5469 git_opts 5470 Any additional options to add to git command itself (not the 5471 ``worktree`` subcommand), in a single string. This is useful for 5472 passing ``-c`` to run git with temporary changes to the git 5473 configuration. 5474 5475 .. versionadded:: 2017.7.0 5476 5477 .. note:: 5478 This is only supported in git 1.7.2 and newer. 5479 5480 user 5481 User under which to run the git command. By default, the command is run 5482 by the user under which the minion is running. 5483 5484 password 5485 Windows only. Required when specifying ``user``. This parameter will be 5486 ignored on non-Windows platforms. 5487 5488 .. versionadded:: 2016.3.4 5489 5490 ignore_retcode : False 5491 If ``True``, do not log an error to the minion log if the git command 5492 returns a nonzero exit status. 5493 5494 .. versionadded:: 2015.8.0 5495 5496 output_encoding 5497 Use this option to specify which encoding to use to decode the output 5498 from any git commands which are run. This should not be needed in most 5499 cases. 5500 5501 .. note:: 5502 This should only be needed if the files in the repository were 5503 created with filenames using an encoding other than UTF-8 to handle 5504 Unicode characters. 5505 5506 .. versionadded:: 2018.3.1 5507 5508 .. _`git-worktree(1)`: http://git-scm.com/docs/git-worktree 5509 .. _`git-config(1)`: http://git-scm.com/docs/git-config/2.5.1 5510 5511 CLI Examples: 5512 5513 .. code-block:: bash 5514 5515 salt myminion git.worktree_prune /path/to/repo 5516 salt myminion git.worktree_prune /path/to/repo dry_run=True 5517 salt myminion git.worktree_prune /path/to/repo expire=1.day.ago 5518 """ 5519 _check_worktree_support() 5520 cwd = _expand_path(cwd, user) 5521 command = ["git"] + _format_git_opts(git_opts) 5522 command.extend(["worktree", "prune"]) 5523 if dry_run: 5524 command.append("--dry-run") 5525 if verbose: 5526 command.append("--verbose") 5527 if expire: 5528 command.extend(["--expire", expire]) 5529 command.extend(_format_opts(opts)) 5530 return _git_run( 5531 command, 5532 cwd=cwd, 5533 user=user, 5534 password=password, 5535 ignore_retcode=ignore_retcode, 5536 output_encoding=output_encoding, 5537 )["stdout"] 5538 5539 5540def worktree_rm(cwd, user=None, output_encoding=None): 5541 """ 5542 .. versionadded:: 2015.8.0 5543 5544 Recursively removes the worktree located at ``cwd``, returning ``True`` if 5545 successful. This function will attempt to determine if ``cwd`` is actually 5546 a worktree by invoking :py:func:`git.is_worktree 5547 <salt.modules.git.is_worktree>`. If the path does not correspond to a 5548 worktree, then an error will be raised and no action will be taken. 5549 5550 .. warning:: 5551 5552 There is no undoing this action. Be **VERY** careful before running 5553 this function. 5554 5555 cwd 5556 Path to the worktree to be removed 5557 5558 user 5559 Used for path expansion when ``cwd`` is not an absolute path. By 5560 default, when ``cwd`` is not absolute, the path will be assumed to be 5561 relative to the home directory of the user under which the minion is 5562 running. Setting this option will change the home directory from which 5563 path expansion is performed. 5564 5565 output_encoding 5566 Use this option to specify which encoding to use to decode the output 5567 from any git commands which are run. This should not be needed in most 5568 cases. 5569 5570 .. note:: 5571 This should only be needed if the files in the repository were 5572 created with filenames using an encoding other than UTF-8 to handle 5573 Unicode characters. 5574 5575 .. versionadded:: 2018.3.1 5576 5577 CLI Examples: 5578 5579 .. code-block:: bash 5580 5581 salt myminion git.worktree_rm /path/to/worktree 5582 """ 5583 _check_worktree_support() 5584 cwd = _expand_path(cwd, user) 5585 if not os.path.exists(cwd): 5586 raise CommandExecutionError(cwd + " does not exist") 5587 elif not is_worktree(cwd, output_encoding=output_encoding): 5588 raise CommandExecutionError(cwd + " is not a git worktree") 5589 try: 5590 salt.utils.files.rm_rf(cwd) 5591 except Exception as exc: # pylint: disable=broad-except 5592 raise CommandExecutionError("Unable to remove {}: {}".format(cwd, exc)) 5593 return True 5594