Skip to content

Commit 5a798fb

Browse files
author
Junio C Hamano
committed
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 <junkio@cox.net>
1 parent 130fcca commit 5a798fb

File tree

1 file changed

+73
-40
lines changed

1 file changed

+73
-40
lines changed

git-commit.sh

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,30 @@ initial_commit=t
1313

1414
refuse_partial () {
1515
echo >&2 "$1"
16-
echo >&2 "Experienced git users:"
1716
echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
1817
exit 1
1918
}
2019

20+
SAVE_INDEX="$GIT_DIR/save-index$$"
21+
save_index () {
22+
cp "$GIT_DIR/index" "$SAVE_INDEX"
23+
}
24+
25+
run_status () {
26+
(
27+
cd "$TOP"
28+
if test '' != "$TMP_INDEX"
29+
then
30+
GIT_INDEX_FILE="$TMP_INDEX" git-status
31+
else
32+
git-status
33+
fi
34+
)
35+
}
36+
2137
all=
2238
also=
39+
only=
2340
logfile=
2441
use_commit=
2542
no_edit=
@@ -73,6 +90,10 @@ do
7390
also=t
7491
shift
7592
;;
93+
-o|--o|--on|--onl|--only)
94+
only=t
95+
shift
96+
;;
7697
-m|--m|--me|--mes|--mess|--messa|--messag|--message)
7798
case "$#" in 1) usage ;; esac
7899
shift
@@ -153,7 +174,7 @@ do
153174
;;
154175
-v|--v|--ve|--ver|--veri|--verif|--verify)
155176
verify=t
156-
shift
177+
shift
157178
;;
158179
--)
159180
shift
@@ -173,19 +194,41 @@ tt*)
173194
die "Only one of -c/-C/-F/-m can be used." ;;
174195
esac
175196

197+
case "$#,$also$only" in
198+
*,tt)
199+
die "Only one of --include/--only can be used." ;;
200+
0,t)
201+
die "No paths with --include/--only does not make sense." ;;
202+
0,)
203+
;;
204+
*,)
205+
echo >&2 "assuming --include paths..."
206+
also=t
207+
# Later when switch the defaults, we will replace them with these:
208+
# echo >&2 "assuming --only paths..."
209+
# also=
210+
;;
211+
esac
212+
unset only
213+
176214
TOP=`git-rev-parse --show-cdup`
215+
if test -z "$TOP"
216+
then
217+
TOP=./
218+
fi
177219

178220
case "$all,$also" in
179221
t,t)
180222
die "Cannot use -a and -i at the same time." ;;
181223
t,)
182-
SAVE_INDEX="$GIT_DIR/save-index$$" &&
183-
cp "$GIT_DIR/index" "$SAVE_INDEX" &&
224+
case "$#" in
225+
0) ;;
226+
*) die "Paths with -a does not make sense." ;;
227+
esac
228+
229+
save_index &&
184230
(
185-
if test '' != "$TOP"
186-
then
187-
cd "$TOP"
188-
fi &&
231+
cd "$TOP"
189232
git-diff-files --name-only -z |
190233
git-update-index --remove -z --stdin
191234
)
@@ -194,10 +237,10 @@ t,)
194237
case "$#" in
195238
0) die "No paths with -i does not make sense." ;;
196239
esac
197-
SAVE_INDEX="$GIT_DIR/save-index$$" &&
198-
cp "$GIT_DIR/index" "$SAVE_INDEX" &&
240+
241+
save_index &&
199242
git-diff-files --name-only -z -- "$@" |
200-
git-update-index --remove -z --stdin
243+
(cd "$TOP" && git-update-index --remove -z --stdin)
201244
;;
202245
,)
203246
case "$#" in
@@ -214,10 +257,9 @@ t,)
214257
# make sure index is clean at the specified paths, or
215258
# they are additions.
216259
dirty_in_index=`git-diff-index --cached --name-status \
217-
--diff-filter=DMTXU HEAD -- "$@"`
260+
--diff-filter=DMTU HEAD -- "$@"`
218261
test -z "$dirty_in_index" ||
219-
refuse_partial "Cannot do a partial commit of paths dirty in index:
220-
262+
refuse_partial "Different in index and the last commit:
221263
$dirty_in_index"
222264
fi
223265
commit_only=`git-ls-files -- "$@"` ;;
@@ -228,7 +270,9 @@ esac
228270
git-update-index -q --refresh || exit 1
229271

230272
trap '
231-
test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
273+
test -z "$TMP_INDEX" || {
274+
test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
275+
}
232276
test -f "$SAVE_INDEX" && mv -f "$SAVE_INDEX" "$GIT_DIR/index"
233277
' 0
234278

@@ -242,12 +286,10 @@ then
242286
fi || exit
243287
echo "$commit_only" |
244288
GIT_INDEX_FILE="$TMP_INDEX" git-update-index --add --remove --stdin &&
289+
save_index &&
245290
echo "$commit_only" |
246291
git-update-index --remove --stdin ||
247292
exit
248-
else
249-
#
250-
:
251293
fi
252294

253295
if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
@@ -303,7 +345,15 @@ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
303345
fi >>"$GIT_DIR"/COMMIT_EDITMSG
304346

305347
# Author
306-
if test '' != "$use_commit"
348+
if test '' != "$force_author"
349+
then
350+
GIT_AUTHOR_NAME=`expr "$force_author" : '\(.*[^ ]\) *<.*'` &&
351+
GIT_AUTHOR_EMAIL=`expr "$force_author" : '.*\(<.*\)'` &&
352+
test '' != "$GIT_AUTHOR_NAME" &&
353+
test '' != "$GIT_AUTHOR_EMAIL" ||
354+
die "malformatted --author parameter"
355+
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
356+
elif test '' != "$use_commit"
307357
then
308358
pick_author_script='
309359
/^author /{
@@ -332,14 +382,6 @@ then
332382
export GIT_AUTHOR_NAME
333383
export GIT_AUTHOR_EMAIL
334384
export GIT_AUTHOR_DATE
335-
elif test '' != "$force_author"
336-
then
337-
GIT_AUTHOR_NAME=`expr "$force_author" : '\(.*[^ ]\) *<.*'` &&
338-
GIT_AUTHOR_EMAIL=`expr "$force_author" : '.*\(<.*\)'` &&
339-
test '' != "$GIT_AUTHOR_NAME" &&
340-
test '' != "$GIT_AUTHOR_EMAIL" ||
341-
die "malformatted --author parameter"
342-
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
343385
fi
344386

345387
PARENTS="-p HEAD"
@@ -350,27 +392,18 @@ then
350392
fi
351393
else
352394
if [ -z "$(git-ls-files)" ]; then
353-
echo Nothing to commit 1>&2
395+
echo >&2 Nothing to commit
354396
exit 1
355397
fi
356398
PARENTS=""
357399
fi
358400

359-
(
360-
if test '' != "$TOP"
361-
then
362-
cd "$TOP"
363-
fi &&
364-
git-status >>"$GIT_DIR"/COMMIT_EDITMSG
365-
)
401+
402+
run_status >>"$GIT_DIR"/COMMIT_EDITMSG
366403
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
367404
then
368405
rm -f "$GIT_DIR/COMMIT_EDITMSG"
369-
if test '' != "$TOP"
370-
then
371-
cd "$TOP"
372-
fi &&
373-
git-status
406+
run_status
374407
exit 1
375408
fi
376409
case "$no_edit" in

0 commit comments

Comments
 (0)