THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

799 lines
16KB

  1. #!/bin/sh
  2. # Copyright (c) 2007, Nanako Shiraishi
  3. dashless=$(basename "$0" | sed -e 's/-/ /')
  4. USAGE="list [<options>]
  5. or: $dashless show [<stash>]
  6. or: $dashless drop [-q|--quiet] [<stash>]
  7. or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
  8. or: $dashless branch <branchname> [<stash>]
  9. or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
  10. [-u|--include-untracked] [-a|--all] [<message>]
  11. or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]
  12. [-u|--include-untracked] [-a|--all] [-m <message>]
  13. [-- <pathspec>...]]
  14. or: $dashless clear"
  15. SUBDIRECTORY_OK=Yes
  16. OPTIONS_SPEC=
  17. START_DIR=$(pwd)
  18. . git-sh-setup
  19. require_work_tree
  20. prefix=$(git rev-parse --show-prefix) || exit 1
  21. cd_to_toplevel
  22. TMP="$GIT_DIR/.git-stash.$$"
  23. TMPindex=${GIT_INDEX_FILE-"$(git rev-parse --git-path index)"}.stash.$$
  24. trap 'rm -f "$TMP-"* "$TMPindex"' 0
  25. ref_stash=refs/stash
  26. if git config --get-colorbool color.interactive; then
  27. help_color="$(git config --get-color color.interactive.help 'red bold')"
  28. reset_color="$(git config --get-color '' reset)"
  29. else
  30. help_color=
  31. reset_color=
  32. fi
  33. no_changes () {
  34. git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
  35. git diff-files --quiet --ignore-submodules -- "$@" &&
  36. (test -z "$untracked" || test -z "$(untracked_files "$@")")
  37. }
  38. untracked_files () {
  39. if test "$1" = "-z"
  40. then
  41. shift
  42. z=-z
  43. else
  44. z=
  45. fi
  46. excl_opt=--exclude-standard
  47. test "$untracked" = "all" && excl_opt=
  48. git ls-files -o $z $excl_opt -- "$@"
  49. }
  50. prepare_fallback_ident () {
  51. if ! git -c user.useconfigonly=yes var GIT_COMMITTER_IDENT >/dev/null 2>&1
  52. then
  53. GIT_AUTHOR_NAME="git stash"
  54. GIT_AUTHOR_EMAIL=git@stash
  55. GIT_COMMITTER_NAME="git stash"
  56. GIT_COMMITTER_EMAIL=git@stash
  57. export GIT_AUTHOR_NAME
  58. export GIT_AUTHOR_EMAIL
  59. export GIT_COMMITTER_NAME
  60. export GIT_COMMITTER_EMAIL
  61. fi
  62. }
  63. clear_stash () {
  64. if test $# != 0
  65. then
  66. die "$(gettext "git stash clear with parameters is unimplemented")"
  67. fi
  68. if current=$(git rev-parse --verify --quiet $ref_stash)
  69. then
  70. git update-ref -d $ref_stash $current
  71. fi
  72. }
  73. maybe_quiet () {
  74. case "$1" in
  75. --keep-stdout)
  76. shift
  77. if test -n "$GIT_QUIET"
  78. then
  79. "$@" 2>/dev/null
  80. else
  81. "$@"
  82. fi
  83. ;;
  84. *)
  85. if test -n "$GIT_QUIET"
  86. then
  87. "$@" >/dev/null 2>&1
  88. else
  89. "$@"
  90. fi
  91. ;;
  92. esac
  93. }
  94. create_stash () {
  95. prepare_fallback_ident
  96. stash_msg=
  97. untracked=
  98. while test $# != 0
  99. do
  100. case "$1" in
  101. -m|--message)
  102. shift
  103. stash_msg=${1?"BUG: create_stash () -m requires an argument"}
  104. ;;
  105. -m*)
  106. stash_msg=${1#-m}
  107. ;;
  108. --message=*)
  109. stash_msg=${1#--message=}
  110. ;;
  111. -u|--include-untracked)
  112. shift
  113. untracked=${1?"BUG: create_stash () -u requires an argument"}
  114. ;;
  115. --)
  116. shift
  117. break
  118. ;;
  119. esac
  120. shift
  121. done
  122. git update-index -q --refresh
  123. if maybe_quiet no_changes "$@"
  124. then
  125. exit 0
  126. fi
  127. # state of the base commit
  128. if b_commit=$(maybe_quiet --keep-stdout git rev-parse --verify HEAD)
  129. then
  130. head=$(git rev-list --oneline -n 1 HEAD --)
  131. elif test -n "$GIT_QUIET"
  132. then
  133. exit 1
  134. else
  135. die "$(gettext "You do not have the initial commit yet")"
  136. fi
  137. if branch=$(git symbolic-ref -q HEAD)
  138. then
  139. branch=${branch#refs/heads/}
  140. else
  141. branch='(no branch)'
  142. fi
  143. msg=$(printf '%s: %s' "$branch" "$head")
  144. # state of the index
  145. i_tree=$(git write-tree) &&
  146. i_commit=$(printf 'index on %s\n' "$msg" |
  147. git commit-tree $i_tree -p $b_commit) ||
  148. die "$(gettext "Cannot save the current index state")"
  149. if test -n "$untracked"
  150. then
  151. # Untracked files are stored by themselves in a parentless commit, for
  152. # ease of unpacking later.
  153. u_commit=$(
  154. untracked_files -z "$@" | (
  155. GIT_INDEX_FILE="$TMPindex" &&
  156. export GIT_INDEX_FILE &&
  157. rm -f "$TMPindex" &&
  158. git update-index -z --add --remove --stdin &&
  159. u_tree=$(git write-tree) &&
  160. printf 'untracked files on %s\n' "$msg" | git commit-tree $u_tree &&
  161. rm -f "$TMPindex"
  162. ) ) || die "$(gettext "Cannot save the untracked files")"
  163. untracked_commit_option="-p $u_commit";
  164. else
  165. untracked_commit_option=
  166. fi
  167. if test -z "$patch_mode"
  168. then
  169. # state of the working tree
  170. w_tree=$( (
  171. git read-tree --index-output="$TMPindex" -m $i_tree &&
  172. GIT_INDEX_FILE="$TMPindex" &&
  173. export GIT_INDEX_FILE &&
  174. git diff-index --name-only -z HEAD -- "$@" >"$TMP-stagenames" &&
  175. git update-index --ignore-skip-worktree-entries \
  176. -z --add --remove --stdin <"$TMP-stagenames" &&
  177. git write-tree &&
  178. rm -f "$TMPindex"
  179. ) ) ||
  180. die "$(gettext "Cannot save the current worktree state")"
  181. else
  182. rm -f "$TMP-index" &&
  183. GIT_INDEX_FILE="$TMP-index" git read-tree HEAD &&
  184. # find out what the user wants
  185. GIT_INDEX_FILE="$TMP-index" \
  186. git add--interactive --patch=stash -- "$@" &&
  187. # state of the working tree
  188. w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
  189. die "$(gettext "Cannot save the current worktree state")"
  190. git diff-tree -p HEAD $w_tree -- >"$TMP-patch" &&
  191. test -s "$TMP-patch" ||
  192. die "$(gettext "No changes selected")"
  193. rm -f "$TMP-index" ||
  194. die "$(gettext "Cannot remove temporary index (can't happen)")"
  195. fi
  196. # create the stash
  197. if test -z "$stash_msg"
  198. then
  199. stash_msg=$(printf 'WIP on %s' "$msg")
  200. else
  201. stash_msg=$(printf 'On %s: %s' "$branch" "$stash_msg")
  202. fi
  203. w_commit=$(printf '%s\n' "$stash_msg" |
  204. git commit-tree $w_tree -p $b_commit -p $i_commit $untracked_commit_option) ||
  205. die "$(gettext "Cannot record working tree state")"
  206. }
  207. store_stash () {
  208. while test $# != 0
  209. do
  210. case "$1" in
  211. -m|--message)
  212. shift
  213. stash_msg="$1"
  214. ;;
  215. -m*)
  216. stash_msg=${1#-m}
  217. ;;
  218. --message=*)
  219. stash_msg=${1#--message=}
  220. ;;
  221. -q|--quiet)
  222. quiet=t
  223. ;;
  224. *)
  225. break
  226. ;;
  227. esac
  228. shift
  229. done
  230. test $# = 1 ||
  231. die "$(eval_gettext "\"$dashless store\" requires one <commit> argument")"
  232. w_commit="$1"
  233. if test -z "$stash_msg"
  234. then
  235. stash_msg="Created via \"git stash store\"."
  236. fi
  237. git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit
  238. ret=$?
  239. test $ret != 0 && test -z "$quiet" &&
  240. die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
  241. return $ret
  242. }
  243. push_stash () {
  244. keep_index=
  245. patch_mode=
  246. untracked=
  247. stash_msg=
  248. while test $# != 0
  249. do
  250. case "$1" in
  251. -k|--keep-index)
  252. keep_index=t
  253. ;;
  254. --no-keep-index)
  255. keep_index=n
  256. ;;
  257. -p|--patch)
  258. patch_mode=t
  259. # only default to keep if we don't already have an override
  260. test -z "$keep_index" && keep_index=t
  261. ;;
  262. -q|--quiet)
  263. GIT_QUIET=t
  264. ;;
  265. -u|--include-untracked)
  266. untracked=untracked
  267. ;;
  268. -a|--all)
  269. untracked=all
  270. ;;
  271. -m|--message)
  272. shift
  273. test -z ${1+x} && usage
  274. stash_msg=$1
  275. ;;
  276. -m*)
  277. stash_msg=${1#-m}
  278. ;;
  279. --message=*)
  280. stash_msg=${1#--message=}
  281. ;;
  282. --help)
  283. show_help
  284. ;;
  285. --)
  286. shift
  287. break
  288. ;;
  289. -*)
  290. option="$1"
  291. eval_gettextln "error: unknown option for 'stash push': \$option"
  292. usage
  293. ;;
  294. *)
  295. break
  296. ;;
  297. esac
  298. shift
  299. done
  300. eval "set $(git rev-parse --sq --prefix "$prefix" -- "$@")"
  301. if test -n "$patch_mode" && test -n "$untracked"
  302. then
  303. die "$(gettext "Can't use --patch and --include-untracked or --all at the same time")"
  304. fi
  305. test -n "$untracked" || git ls-files --error-unmatch -- "$@" >/dev/null || exit 1
  306. git update-index -q --refresh
  307. if maybe_quiet no_changes "$@"
  308. then
  309. say "$(gettext "No local changes to save")"
  310. exit 0
  311. fi
  312. git reflog exists $ref_stash ||
  313. clear_stash || die "$(gettext "Cannot initialize stash")"
  314. create_stash -m "$stash_msg" -u "$untracked" -- "$@"
  315. store_stash -m "$stash_msg" -q $w_commit ||
  316. die "$(gettext "Cannot save the current status")"
  317. say "$(eval_gettext "Saved working directory and index state \$stash_msg")"
  318. if test -z "$patch_mode"
  319. then
  320. test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
  321. if test -n "$untracked" && test $# = 0
  322. then
  323. git clean --force --quiet -d $CLEAN_X_OPTION
  324. fi
  325. if test $# != 0
  326. then
  327. test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION=
  328. test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION=
  329. git add $UPDATE_OPTION $FORCE_OPTION -- "$@"
  330. git diff-index -p --cached --binary HEAD -- "$@" |
  331. git apply --index -R
  332. else
  333. git reset --hard -q --no-recurse-submodules
  334. fi
  335. if test "$keep_index" = "t" && test -n "$i_tree"
  336. then
  337. git read-tree --reset $i_tree
  338. git ls-files -z --modified -- "$@" |
  339. git checkout-index -z --force --stdin
  340. fi
  341. else
  342. git apply -R < "$TMP-patch" ||
  343. die "$(gettext "Cannot remove worktree changes")"
  344. if test "$keep_index" != "t"
  345. then
  346. git reset -q -- "$@"
  347. fi
  348. fi
  349. }
  350. save_stash () {
  351. push_options=
  352. while test $# != 0
  353. do
  354. case "$1" in
  355. -q|--quiet)
  356. GIT_QUIET=t
  357. ;;
  358. --)
  359. shift
  360. break
  361. ;;
  362. -*)
  363. # pass all options through to push_stash
  364. push_options="$push_options $1"
  365. ;;
  366. *)
  367. break
  368. ;;
  369. esac
  370. shift
  371. done
  372. stash_msg="$*"
  373. if test -z "$stash_msg"
  374. then
  375. push_stash $push_options
  376. else
  377. push_stash $push_options -m "$stash_msg"
  378. fi
  379. }
  380. have_stash () {
  381. git rev-parse --verify --quiet $ref_stash >/dev/null
  382. }
  383. list_stash () {
  384. have_stash || return 0
  385. git log --format="%gd: %gs" -g --first-parent -m "$@" $ref_stash --
  386. }
  387. show_stash () {
  388. ALLOW_UNKNOWN_FLAGS=t
  389. assert_stash_like "$@"
  390. if test -z "$FLAGS"
  391. then
  392. if test "$(git config --bool stash.showStat || echo true)" = "true"
  393. then
  394. FLAGS=--stat
  395. fi
  396. if test "$(git config --bool stash.showPatch || echo false)" = "true"
  397. then
  398. FLAGS=${FLAGS}${FLAGS:+ }-p
  399. fi
  400. if test -z "$FLAGS"
  401. then
  402. return 0
  403. fi
  404. fi
  405. git diff ${FLAGS} $b_commit $w_commit
  406. }
  407. show_help () {
  408. exec git help stash
  409. exit 1
  410. }
  411. #
  412. # Parses the remaining options looking for flags and
  413. # at most one revision defaulting to ${ref_stash}@{0}
  414. # if none found.
  415. #
  416. # Derives related tree and commit objects from the
  417. # revision, if one is found.
  418. #
  419. # stash records the work tree, and is a merge between the
  420. # base commit (first parent) and the index tree (second parent).
  421. #
  422. # REV is set to the symbolic version of the specified stash-like commit
  423. # IS_STASH_LIKE is non-blank if ${REV} looks like a stash
  424. # IS_STASH_REF is non-blank if the ${REV} looks like a stash ref
  425. # s is set to the SHA1 of the stash commit
  426. # w_commit is set to the commit containing the working tree
  427. # b_commit is set to the base commit
  428. # i_commit is set to the commit containing the index tree
  429. # u_commit is set to the commit containing the untracked files tree
  430. # w_tree is set to the working tree
  431. # b_tree is set to the base tree
  432. # i_tree is set to the index tree
  433. # u_tree is set to the untracked files tree
  434. #
  435. # GIT_QUIET is set to t if -q is specified
  436. # INDEX_OPTION is set to --index if --index is specified.
  437. # FLAGS is set to the remaining flags (if allowed)
  438. #
  439. # dies if:
  440. # * too many revisions specified
  441. # * no revision is specified and there is no stash stack
  442. # * a revision is specified which cannot be resolve to a SHA1
  443. # * a non-existent stash reference is specified
  444. # * unknown flags were set and ALLOW_UNKNOWN_FLAGS is not "t"
  445. #
  446. parse_flags_and_rev()
  447. {
  448. test "$PARSE_CACHE" = "$*" && return 0 # optimisation
  449. PARSE_CACHE="$*"
  450. IS_STASH_LIKE=
  451. IS_STASH_REF=
  452. INDEX_OPTION=
  453. s=
  454. w_commit=
  455. b_commit=
  456. i_commit=
  457. u_commit=
  458. w_tree=
  459. b_tree=
  460. i_tree=
  461. u_tree=
  462. FLAGS=
  463. REV=
  464. for opt
  465. do
  466. case "$opt" in
  467. -q|--quiet)
  468. GIT_QUIET=-t
  469. ;;
  470. --index)
  471. INDEX_OPTION=--index
  472. ;;
  473. --help)
  474. show_help
  475. ;;
  476. -*)
  477. test "$ALLOW_UNKNOWN_FLAGS" = t ||
  478. die "$(eval_gettext "unknown option: \$opt")"
  479. FLAGS="${FLAGS}${FLAGS:+ }$opt"
  480. ;;
  481. *)
  482. REV="${REV}${REV:+ }'$opt'"
  483. ;;
  484. esac
  485. done
  486. eval set -- $REV
  487. case $# in
  488. 0)
  489. have_stash || die "$(gettext "No stash entries found.")"
  490. set -- ${ref_stash}@{0}
  491. ;;
  492. 1)
  493. :
  494. ;;
  495. *)
  496. die "$(eval_gettext "Too many revisions specified: \$REV")"
  497. ;;
  498. esac
  499. case "$1" in
  500. *[!0-9]*)
  501. :
  502. ;;
  503. *)
  504. set -- "${ref_stash}@{$1}"
  505. ;;
  506. esac
  507. REV=$(git rev-parse --symbolic --verify --quiet "$1") || {
  508. reference="$1"
  509. die "$(eval_gettext "\$reference is not a valid reference")"
  510. }
  511. i_commit=$(git rev-parse --verify --quiet "$REV^2") &&
  512. set -- $(git rev-parse "$REV" "$REV^1" "$REV:" "$REV^1:" "$REV^2:" 2>/dev/null) &&
  513. s=$1 &&
  514. w_commit=$1 &&
  515. b_commit=$2 &&
  516. w_tree=$3 &&
  517. b_tree=$4 &&
  518. i_tree=$5 &&
  519. IS_STASH_LIKE=t &&
  520. test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
  521. IS_STASH_REF=t
  522. u_commit=$(git rev-parse --verify --quiet "$REV^3") &&
  523. u_tree=$(git rev-parse "$REV^3:" 2>/dev/null)
  524. }
  525. is_stash_like()
  526. {
  527. parse_flags_and_rev "$@"
  528. test -n "$IS_STASH_LIKE"
  529. }
  530. assert_stash_like() {
  531. is_stash_like "$@" || {
  532. args="$*"
  533. die "$(eval_gettext "'\$args' is not a stash-like commit")"
  534. }
  535. }
  536. is_stash_ref() {
  537. is_stash_like "$@" && test -n "$IS_STASH_REF"
  538. }
  539. assert_stash_ref() {
  540. is_stash_ref "$@" || {
  541. args="$*"
  542. die "$(eval_gettext "'\$args' is not a stash reference")"
  543. }
  544. }
  545. apply_stash () {
  546. assert_stash_like "$@"
  547. git update-index -q --refresh || die "$(gettext "unable to refresh index")"
  548. # current index state
  549. c_tree=$(git write-tree) ||
  550. die "$(gettext "Cannot apply a stash in the middle of a merge")"
  551. unstashed_index_tree=
  552. if test -n "$INDEX_OPTION" && test "$b_tree" != "$i_tree" &&
  553. test "$c_tree" != "$i_tree"
  554. then
  555. git diff-tree --binary $s^2^..$s^2 | git apply --cached
  556. test $? -ne 0 &&
  557. die "$(gettext "Conflicts in index. Try without --index.")"
  558. unstashed_index_tree=$(git write-tree) ||
  559. die "$(gettext "Could not save index tree")"
  560. git reset
  561. fi
  562. if test -n "$u_tree"
  563. then
  564. GIT_INDEX_FILE="$TMPindex" git read-tree "$u_tree" &&
  565. GIT_INDEX_FILE="$TMPindex" git checkout-index --all &&
  566. rm -f "$TMPindex" ||
  567. die "$(gettext "Could not restore untracked files from stash entry")"
  568. fi
  569. eval "
  570. GITHEAD_$w_tree='Stashed changes' &&
  571. GITHEAD_$c_tree='Updated upstream' &&
  572. GITHEAD_$b_tree='Version stash was based on' &&
  573. export GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree
  574. "
  575. if test -n "$GIT_QUIET"
  576. then
  577. GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
  578. fi
  579. if git merge-recursive $b_tree -- $c_tree $w_tree
  580. then
  581. # No conflict
  582. if test -n "$unstashed_index_tree"
  583. then
  584. git read-tree "$unstashed_index_tree"
  585. else
  586. a="$TMP-added" &&
  587. git diff-index --cached --name-only --diff-filter=A $c_tree >"$a" &&
  588. git read-tree --reset $c_tree &&
  589. git update-index --add --stdin <"$a" ||
  590. die "$(gettext "Cannot unstage modified files")"
  591. rm -f "$a"
  592. fi
  593. squelch=
  594. if test -n "$GIT_QUIET"
  595. then
  596. squelch='>/dev/null 2>&1'
  597. fi
  598. (cd "$START_DIR" && eval "git status $squelch") || :
  599. else
  600. # Merge conflict; keep the exit status from merge-recursive
  601. status=$?
  602. git rerere
  603. if test -n "$INDEX_OPTION"
  604. then
  605. gettextln "Index was not unstashed." >&2
  606. fi
  607. exit $status
  608. fi
  609. }
  610. pop_stash() {
  611. assert_stash_ref "$@"
  612. if apply_stash "$@"
  613. then
  614. drop_stash "$@"
  615. else
  616. status=$?
  617. say "$(gettext "The stash entry is kept in case you need it again.")"
  618. exit $status
  619. fi
  620. }
  621. drop_stash () {
  622. assert_stash_ref "$@"
  623. git reflog delete --updateref --rewrite "${REV}" &&
  624. say "$(eval_gettext "Dropped \${REV} (\$s)")" ||
  625. die "$(eval_gettext "\${REV}: Could not drop stash entry")"
  626. # clear_stash if we just dropped the last stash entry
  627. git rev-parse --verify --quiet "$ref_stash@{0}" >/dev/null ||
  628. clear_stash
  629. }
  630. apply_to_branch () {
  631. test -n "$1" || die "$(gettext "No branch name specified")"
  632. branch=$1
  633. shift 1
  634. set -- --index "$@"
  635. assert_stash_like "$@"
  636. git checkout -b $branch $REV^ &&
  637. apply_stash "$@" && {
  638. test -z "$IS_STASH_REF" || drop_stash "$@"
  639. }
  640. }
  641. test "$1" = "-p" && set "push" "$@"
  642. PARSE_CACHE='--not-parsed'
  643. # The default command is "push" if nothing but options are given
  644. seen_non_option=
  645. for opt
  646. do
  647. case "$opt" in
  648. --) break ;;
  649. -*) ;;
  650. *) seen_non_option=t; break ;;
  651. esac
  652. done
  653. test -n "$seen_non_option" || set "push" "$@"
  654. # Main command set
  655. case "$1" in
  656. list)
  657. shift
  658. list_stash "$@"
  659. ;;
  660. show)
  661. shift
  662. show_stash "$@"
  663. ;;
  664. save)
  665. shift
  666. save_stash "$@"
  667. ;;
  668. push)
  669. shift
  670. push_stash "$@"
  671. ;;
  672. apply)
  673. shift
  674. apply_stash "$@"
  675. ;;
  676. clear)
  677. shift
  678. clear_stash "$@"
  679. ;;
  680. create)
  681. shift
  682. create_stash -m "$*" && echo "$w_commit"
  683. ;;
  684. store)
  685. shift
  686. store_stash "$@"
  687. ;;
  688. drop)
  689. shift
  690. drop_stash "$@"
  691. ;;
  692. pop)
  693. shift
  694. pop_stash "$@"
  695. ;;
  696. branch)
  697. shift
  698. apply_to_branch "$@"
  699. ;;
  700. *)
  701. case $# in
  702. 0)
  703. push_stash &&
  704. say "$(gettext "(To restore them type \"git stash apply\")")"
  705. ;;
  706. *)
  707. usage
  708. esac
  709. ;;
  710. esac