From 5a798fb57f788692467b1a11416dd5ebff0d31ae Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 5 Feb 2006 16:08:01 -0800 Subject: [PATCH] git-commit: finishing touches. Introduce --only flag to allow the new "partial commit" semantics when paths are specified. The default is still the traditional --include semantics. Once peoples' fingers and scripts that want the traditional behaviour are updated to explicitly say --include, we could change it to either default to --only, or refuse to operate without either --only/--include when paths are specified. This also fixes a couple of bugs in the previous round. Namely: - forgot to save/restore index in some cases. - forgot to use the temporary index to show status when '--only paths...' semantics was used. - --author did not take precedence when reusing an existing commit. Signed-off-by: Junio C Hamano --- git-commit.sh | 113 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 40 deletions(-) diff --git a/git-commit.sh b/git-commit.sh index 7b9f11b6e..25389240b 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -13,13 +13,30 @@ initial_commit=t refuse_partial () { echo >&2 "$1" - echo >&2 "Experienced git users:" echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?" exit 1 } +SAVE_INDEX="$GIT_DIR/save-index$$" +save_index () { + cp "$GIT_DIR/index" "$SAVE_INDEX" +} + +run_status () { + ( + cd "$TOP" + if test '' != "$TMP_INDEX" + then + GIT_INDEX_FILE="$TMP_INDEX" git-status + else + git-status + fi + ) +} + all= also= +only= logfile= use_commit= no_edit= @@ -73,6 +90,10 @@ do also=t shift ;; + -o|--o|--on|--onl|--only) + only=t + shift + ;; -m|--m|--me|--mes|--mess|--messa|--messag|--message) case "$#" in 1) usage ;; esac shift @@ -153,7 +174,7 @@ do ;; -v|--v|--ve|--ver|--veri|--verif|--verify) verify=t - shift + shift ;; --) shift @@ -173,19 +194,41 @@ tt*) die "Only one of -c/-C/-F/-m can be used." ;; esac +case "$#,$also$only" in +*,tt) + die "Only one of --include/--only can be used." ;; +0,t) + die "No paths with --include/--only does not make sense." ;; +0,) + ;; +*,) + echo >&2 "assuming --include paths..." + also=t + # Later when switch the defaults, we will replace them with these: + # echo >&2 "assuming --only paths..." + # also= + ;; +esac +unset only + TOP=`git-rev-parse --show-cdup` +if test -z "$TOP" +then + TOP=./ +fi case "$all,$also" in t,t) die "Cannot use -a and -i at the same time." ;; t,) - SAVE_INDEX="$GIT_DIR/save-index$$" && - cp "$GIT_DIR/index" "$SAVE_INDEX" && + case "$#" in + 0) ;; + *) die "Paths with -a does not make sense." ;; + esac + + save_index && ( - if test '' != "$TOP" - then - cd "$TOP" - fi && + cd "$TOP" git-diff-files --name-only -z | git-update-index --remove -z --stdin ) @@ -194,10 +237,10 @@ t,) case "$#" in 0) die "No paths with -i does not make sense." ;; esac - SAVE_INDEX="$GIT_DIR/save-index$$" && - cp "$GIT_DIR/index" "$SAVE_INDEX" && + + save_index && git-diff-files --name-only -z -- "$@" | - git-update-index --remove -z --stdin + (cd "$TOP" && git-update-index --remove -z --stdin) ;; ,) case "$#" in @@ -214,10 +257,9 @@ t,) # make sure index is clean at the specified paths, or # they are additions. dirty_in_index=`git-diff-index --cached --name-status \ - --diff-filter=DMTXU HEAD -- "$@"` + --diff-filter=DMTU HEAD -- "$@"` test -z "$dirty_in_index" || - refuse_partial "Cannot do a partial commit of paths dirty in index: - + refuse_partial "Different in index and the last commit: $dirty_in_index" fi commit_only=`git-ls-files -- "$@"` ;; @@ -228,7 +270,9 @@ esac git-update-index -q --refresh || exit 1 trap ' - test -f "$TMP_INDEX" && rm -f "$TMP_INDEX" + test -z "$TMP_INDEX" || { + test -f "$TMP_INDEX" && rm -f "$TMP_INDEX" + } test -f "$SAVE_INDEX" && mv -f "$SAVE_INDEX" "$GIT_DIR/index" ' 0 @@ -242,12 +286,10 @@ then fi || exit echo "$commit_only" | GIT_INDEX_FILE="$TMP_INDEX" git-update-index --add --remove --stdin && + save_index && echo "$commit_only" | git-update-index --remove --stdin || exit -else - # - : fi if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit @@ -303,7 +345,15 @@ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then fi >>"$GIT_DIR"/COMMIT_EDITMSG # Author -if test '' != "$use_commit" +if test '' != "$force_author" +then + GIT_AUTHOR_NAME=`expr "$force_author" : '\(.*[^ ]\) *<.*'` && + GIT_AUTHOR_EMAIL=`expr "$force_author" : '.*\(<.*\)'` && + test '' != "$GIT_AUTHOR_NAME" && + test '' != "$GIT_AUTHOR_EMAIL" || + die "malformatted --author parameter" + export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL +elif test '' != "$use_commit" then pick_author_script=' /^author /{ @@ -332,14 +382,6 @@ then export GIT_AUTHOR_NAME export GIT_AUTHOR_EMAIL export GIT_AUTHOR_DATE -elif test '' != "$force_author" -then - GIT_AUTHOR_NAME=`expr "$force_author" : '\(.*[^ ]\) *<.*'` && - GIT_AUTHOR_EMAIL=`expr "$force_author" : '.*\(<.*\)'` && - test '' != "$GIT_AUTHOR_NAME" && - test '' != "$GIT_AUTHOR_EMAIL" || - die "malformatted --author parameter" - export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL fi PARENTS="-p HEAD" @@ -350,27 +392,18 @@ then fi else if [ -z "$(git-ls-files)" ]; then - echo Nothing to commit 1>&2 + echo >&2 Nothing to commit exit 1 fi PARENTS="" fi -( - if test '' != "$TOP" - then - cd "$TOP" - fi && - git-status >>"$GIT_DIR"/COMMIT_EDITMSG -) + +run_status >>"$GIT_DIR"/COMMIT_EDITMSG if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ] then rm -f "$GIT_DIR/COMMIT_EDITMSG" - if test '' != "$TOP" - then - cd "$TOP" - fi && - git-status + run_status exit 1 fi case "$no_edit" in -- 2.30.2