Implement safe_strncpy() as strlcpy() and use it more.
[gitweb.git] / git-commit.sh
index 330a434b1891a67f78dfbb665558efef868bb704..6dd04fd3675fd2559f983581a9d5f7eddee31e55 100755 (executable)
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Linus Torvalds
 # Copyright (c) 2006 Junio C Hamano
 
-USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>) [--amend] [-e] [--author <author>] [[-i | -o] <path>...]'
+USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-u] [--amend] [-e] [--author <author>] [[-i | -o] <path>...]'
 SUBDIRECTORY_OK=Yes
 . git-sh-setup
 
@@ -134,13 +134,17 @@ run_status () {
        report "Changed but not updated" \
            "use git-update-index to mark for commit"
 
+        option=""
+        if test -z "$untracked_files"; then
+            option="--directory --no-empty-directory"
+        fi
        if test -f "$GIT_DIR/info/exclude"
        then
-           git-ls-files -z --others --directory \
+           git-ls-files -z --others $option \
                --exclude-from="$GIT_DIR/info/exclude" \
                --exclude-per-directory=.gitignore
        else
-           git-ls-files -z --others --directory \
+           git-ls-files -z --others $option \
                --exclude-per-directory=.gitignore
        fi |
        perl -e '$/ = "\0";
@@ -161,14 +165,19 @@ run_status () {
            }
        '
 
-       if test -n "$verbose"
+       if test -n "$verbose" -a -z "$IS_INITIAL"
        then
            git-diff-index --cached -M -p --diff-filter=MDTCRA $REFERENCE
        fi
        case "$committable" in
        0)
-           echo "nothing to commit"
-           exit 1
+               case "$amend" in
+               t)
+                       echo "# No changes" ;;
+               *)
+                       echo "nothing to commit" ;;
+               esac
+               exit 1 ;;
        esac
        exit 0
     )
@@ -198,6 +207,7 @@ verbose=
 signoff=
 force_author=
 only_include_assumed=
+untracked_files=
 while case "$#" in 0) break;; esac
 do
   case "$1" in
@@ -250,20 +260,41 @@ do
   -m|--m|--me|--mes|--mess|--messa|--messag|--message)
       case "$#" in 1) usage ;; esac
       shift
-      log_given=t$log_given
-      log_message="$1"
+      log_given=m$log_given
+      if test "$log_message" = ''
+      then
+          log_message="$1"
+      else
+          log_message="$log_message
+
+$1"
+      fi
       no_edit=t
       shift
       ;;
   -m*)
-      log_given=t$log_given
-      log_message=`expr "$1" : '-m\(.*\)'`
+      log_given=m$log_given
+      if test "$log_message" = ''
+      then
+          log_message=`expr "$1" : '-m\(.*\)'`
+      else
+          log_message="$log_message
+
+`expr "$1" : '-m\(.*\)'`"
+      fi
       no_edit=t
       shift
       ;;
   --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
-      log_given=t$log_given
-      log_message=`expr "$1" : '-[^=]*=\(.*\)'`
+      log_given=m$log_given
+      if test "$log_message" = ''
+      then
+          log_message=`expr "$1" : '-[^=]*=\(.*\)'`
+      else
+          log_message="$log_message
+
+`expr "$1" : '-[^=]*=\(.*\)'`"
+      fi
       no_edit=t
       shift
       ;;
@@ -335,6 +366,12 @@ do
       verbose=t
       shift
       ;;
+  -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|--untracked|\
+  --untracked-|--untracked-f|--untracked-fi|--untracked-fil|--untracked-file|\
+  --untracked-files)
+      untracked_files=t
+      shift
+      ;;
   --)
       shift
       break
@@ -362,17 +399,21 @@ esac
 
 case "$log_given" in
 tt*)
-  die "Only one of -c/-C/-F/-m can be used." ;;
+  die "Only one of -c/-C/-F can be used." ;;
+*tm*|*mt*)
+  die "Option -m cannot be combined with -c/-C/-F." ;;
 esac
 
-case "$#,$also$only" in
-*,tt)
+case "$#,$also,$only,$amend" in
+*,t,t,*)
   die "Only one of --include/--only can be used." ;;
-0,t)
+0,t,,* | 0,,t,)
   die "No paths with --include/--only does not make sense." ;;
-0,)
+0,,t,t)
+  only_include_assumed="# Clever... amending the last one with dirty index." ;;
+0,,,*)
   ;;
-*,)
+*,,,*)
   only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
   also=
   ;;
@@ -537,7 +578,7 @@ t)
        ;;
 esac
 
-if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
        echo "#"
        echo "# It looks like you may be committing a MERGE."
        echo "# If this is not correct, please remove the file"
@@ -549,8 +590,8 @@ fi >>"$GIT_DIR"/COMMIT_EDITMSG
 # Author
 if test '' != "$force_author"
 then
-       GIT_AUTHOR_NAME=`expr "$force_author" : '\(.*[^ ]\) *<.*'` &&
-       GIT_AUTHOR_EMAIL=`expr "$force_author" : '.*\(<.*\)'` &&
+       GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+       GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
        test '' != "$GIT_AUTHOR_NAME" &&
        test '' != "$GIT_AUTHOR_EMAIL" ||
        die "malformatted --author parameter"
@@ -605,16 +646,26 @@ else
        current=
 fi
 
-{
-       test -z "$only_include_assumed" || echo "$only_include_assumed"
-       run_status
-} >>"$GIT_DIR"/COMMIT_EDITMSG
+if test -z "$no_edit"
+then
+       {
+               echo ""
+               echo "# Please enter the commit message for your changes."
+               echo "# (Comment lines starting with '#' will not be included)"
+               test -z "$only_include_assumed" || echo "$only_include_assumed"
+               run_status
+       } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+       # we need to check if there is anything to commit
+       run_status >/dev/null 
+fi
 if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
 then
        rm -f "$GIT_DIR/COMMIT_EDITMSG"
        run_status
        exit 1
 fi
+
 case "$no_edit" in
 '')
        case "${VISUAL:-$EDITOR},$TERM" in
@@ -626,6 +677,8 @@ case "$no_edit" in
                exit 1
                ;;
        esac
+       git-var GIT_AUTHOR_IDENT > /dev/null  || die
+       git-var GIT_COMMITTER_IDENT > /dev/null  || die
        ${VISUAL:-${EDITOR:-vi}} "$GIT_DIR/COMMIT_EDITMSG"
        ;;
 esac
@@ -660,7 +713,8 @@ then
                rm -f "$TMP_INDEX"
        fi &&
        commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
-       git-update-ref HEAD $commit $current &&
+       rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
+       git-update-ref -m "commit: $rlogm" HEAD $commit $current &&
        rm -f -- "$GIT_DIR/MERGE_HEAD" &&
        if test -f "$NEXT_INDEX"
        then