Merge with master.
authorJunio C Hamano <junkio@cox.net>
Wed, 10 Aug 2005 07:10:18 +0000 (00:10 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 10 Aug 2005 07:10:18 +0000 (00:10 -0700)
This merges commit
    c35a7b8d806317dc1762e36561cbd31c2530dd9c
from master into our head commit
    edee414c3e5a546aae3dd1529f397df949713305

Sincerely,
    jit-merge command.

30 files changed:
Documentation/git-commit-script.txt [new file with mode: 0644]
Documentation/git-ls-remote-script.txt [new file with mode: 0644]
Documentation/git.txt
Makefile
apply.c
cache.h
clone-pack.c
commit.c
commit.h
connect.c
convert-cache.c
csum-file.h
diff.c
git-cherry
git-commit-script
git-format-patch-script
git-ls-remote-script
git-push-script
git-rebase-script
git-reset-script
git-revert-script [new file with mode: 0755]
pack-check.c
pkt-line.h
refs.c
rev-list.c
rev-parse.c
rsh.c
sha1_file.c
tar-tree.c
tools/mailsplit.c

diff --git a/Documentation/git-commit-script.txt b/Documentation/git-commit-script.txt
new file mode 100644 (file)
index 0000000..bb559d7
--- /dev/null
@@ -0,0 +1,49 @@
+git-commit-script(1)
+====================
+v0.99.4, Aug 2005
+
+NAME
+----
+git-commit-script - Record your changes
+
+SYNOPSIS
+--------
+'git commit' [-a] [(-c | -C) <commit> | -F <file> | -m <msg>] <file>...
+
+DESCRIPTION
+-----------
+Updates the index file for given paths, or all modified files if
+'-a' is specified, and makes a commit object.  The command
+VISUAL and EDITOR environment variables to edit the commit log
+message.
+
+OPTIONS
+-------
+-a::
+       Update all paths in the index file.
+
+-c or -C <commit>::
+       Take existing commit object, and reuse the log message
+       and the authorship information (including the timestamp)
+       when creating the commit.  With '-C', the editor is not
+       invoked; with '-c' the user can further edit the commit
+       message.
+
+-F <file>::
+       Take the commit message from the given file.  Use '-' to
+       read the message from the standard input.
+
+-m <msg>::
+       Use the given <msg> as the commit message.
+
+<file>...::
+       Update specified paths in the index file.
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+GIT
+---
+Part of the link:git.html[git] suite
diff --git a/Documentation/git-ls-remote-script.txt b/Documentation/git-ls-remote-script.txt
new file mode 100644 (file)
index 0000000..0b98e6a
--- /dev/null
@@ -0,0 +1,64 @@
+git-ls-remote-script(1)
+=======================
+v0.1, May 2005
+
+NAME
+----
+git-ls-remote-script - Look at references other repository has.
+
+
+SYNOPSIS
+--------
+'git-ls-remote' [--heads] [--tags] <repository> <refs>...
+
+DESCRIPTION
+-----------
+Displays the references other repository has.
+
+
+OPTIONS
+-------
+--heads --tags::
+       Limit to only refs/heads and refs/tags, respectively.
+       These options are _not_ mutually exclusive; when given
+       both, references stored in refs/heads and refs/tags are
+       displayed.
+
+<repository>::
+       Location of the repository.  The shorthand defined in
+       $GIT_DIR/branches/ can be used.
+
+<refs>...::
+       When unspecified, all references, after filtering done
+       with --heads and --tags, are shown.  When <refs>... are
+       specified, only references matching the given patterns
+       are displayed.
+
+EXAMPLES
+--------
+
+       $ git ls-remote --tags ./.
+       d6602ec5194c87b0fc87103ca4d67251c76f233a        refs/tags/v0.99
+       f25a265a342aed6041ab0cc484224d9ca54b6f41        refs/tags/v0.99.1
+       7ceca275d047c90c0c7d5afb13ab97efdf51bd6e        refs/tags/v0.99.3
+       c5db5456ae3b0873fc659c19fafdde22313cc441        refs/tags/v0.99.2
+       0918385dbd9656cab0d1d81ba7453d49bbc16250        refs/tags/junio-gpg-pub
+       $ git ls-remote http://www.kernel.org/pub/scm/git/git.git master pu rc
+       5fe978a5381f1fbad26a80e682ddd2a401966740        refs/heads/master
+       c781a84b5204fb294c9ccc79f8b3baceeb32c061        refs/heads/pu
+       b1d096f2926c4e37c9c0b6a7bf2119bedaa277cb        refs/heads/rc
+       $ echo http://www.kernel.org/pub/scm/git/git.git >.git/branches/public
+       $ git ls-remote --tags public v\*
+       d6602ec5194c87b0fc87103ca4d67251c76f233a        refs/tags/v0.99
+       f25a265a342aed6041ab0cc484224d9ca54b6f41        refs/tags/v0.99.1
+       c5db5456ae3b0873fc659c19fafdde22313cc441        refs/tags/v0.99.2
+       7ceca275d047c90c0c7d5afb13ab97efdf51bd6e        refs/tags/v0.99.3
+
+Author
+------
+Written by Junio C Hamano <junkio@cox.net>
+
+GIT
+---
+Part of the link:git.html[git] suite
+
index d18cf5e..1308eb6 100644 (file)
@@ -34,6 +34,10 @@ the repository, the cache and the working fileset, those that
 interrogate and compare them, and those that moves objects and
 references between repositories.
 
+In addition, git itself comes with a spartan set of porcelain
+commands.  They are usable but are not meant to compete with real
+Porcelains.
+
 There are also some ancilliary programs that can be viewed as useful
 aids for using the core commands but which are unlikely to be used by
 SCMs layered over git.
@@ -128,14 +132,6 @@ link:git-clone-pack.html[git-clone-pack]::
        Clones a repository into the current repository (engine
        for ssh and local transport)
 
-link:git-fetch-script.html[git-fetch-script]::
-       Download from a remote repository via various protocols
-       (user interface).
-
-link:git-pull-script.html[git-pull-script]::
-       Fetch from and merge with a remote repository via
-       various protocols (user interface).
-
 link:git-http-pull.html[git-http-pull]::
        Downloads a remote GIT repository via HTTP
 
@@ -169,6 +165,18 @@ link:git-update-server-info.html[git-update-server-info]::
        clients discover references and packs on it.
 
 
+Porcelainish Commands
+---------------------
+link:git-fetch-script.html[git-fetch-script]::
+       Download from a remote repository via various protocols.
+
+link:git-pull-script.html[git-pull-script]::
+       Fetch from and merge with a remote repository.
+
+link:git-commit-script.html[git-commit-script]::
+       Record changes to the repository.
+
+
 Ancilliary Commands
 -------------------
 Manipulators:
index df5f8c0..e0ea88f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \
 
 SCRIPTS += git-count-objects-script
 # SCRIPTS += git-send-email-script
+SCRIPTS += git-revert-script
 
 PROG=   git-update-cache git-diff-files git-init-db git-write-tree \
        git-read-tree git-commit-tree git-cat-file git-fsck-cache \
diff --git a/apply.c b/apply.c
index c671d9e..81607c0 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -563,7 +563,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
                        struct fragment dummy;
                        if (parse_fragment_header(line, len, &dummy) < 0)
                                continue;
-                       error("patch fragment without header at line %d: %.*s", linenr, len-1, line);
+                       error("patch fragment without header at line %d: %.*s", linenr, (int)len-1, line);
                }
 
                if (size < len + 6)
@@ -968,7 +968,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
 
        while (frag) {
                if (apply_one_fragment(desc, frag) < 0)
-                       return error("patch failed: %s:%d", patch->old_name, frag->oldpos);
+                       return error("patch failed: %s:%ld", patch->old_name, frag->oldpos);
                frag = frag->next;
        }
        return 0;
diff --git a/cache.h b/cache.h
index 957e2ca..efd2a2c 100644 (file)
--- a/cache.h
+++ b/cache.h
 #define NORETURN
 #endif
 
+#ifndef __attribute__
+#define __attribute(x)
+#endif
+
 /*
  * Intensive research over the course of many years has shown that
  * port 9418 is totally unused by anything else. Or
@@ -171,8 +175,8 @@ extern void rollback_index_file(struct cache_file *);
 #define TYPE_CHANGED    0x0040
 
 /* Return a statically allocated filename matching the sha1 signature */
-extern char *mkpath(const char *fmt, ...);
-extern char *git_path(const char *fmt, ...);
+extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern char *sha1_file_name(const unsigned char *sha1);
 extern char *sha1_pack_name(const unsigned char *sha1);
 extern char *sha1_pack_index_name(const unsigned char *sha1);
@@ -218,8 +222,8 @@ extern char *sha1_to_hex(const unsigned char *sha1);        /* static buffer result! */
 
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
-extern void die(const char *err, ...) NORETURN;
-extern int error(const char *err, ...);
+extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
 extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
 extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
index e9c20de..49820c6 100644 (file)
@@ -30,7 +30,7 @@ static int is_master(struct ref *ref)
 
 static void write_one_ref(struct ref *ref)
 {
-       char *path = git_path(ref->name);
+       char *path = git_path("%s", ref->name);
        int fd;
        char *hex;
 
index 3ac421a..59e93d4 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -33,6 +33,8 @@ enum cmit_fmt get_commit_format(const char *arg)
                return CMIT_FMT_SHORT;
        if (!strcmp(arg, "=full"))
                return CMIT_FMT_FULL;
+       if (!strcmp(arg, "=oneline"))
+               return CMIT_FMT_ONELINE;
        die("invalid --pretty format");
 }
 
@@ -350,6 +352,8 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c
        unsigned long time;
        int tz, ret;
 
+       if (fmt == CMIT_FMT_ONELINE)
+               return 0;
        date = strchr(line, '>');
        if (!date)
                return 0;
@@ -373,6 +377,9 @@ static int is_empty_line(const char *line, int len)
 static int add_parent_info(enum cmit_fmt fmt, char *buf, const char *line, int parents)
 {
        int offset = 0;
+
+       if (fmt == CMIT_FMT_ONELINE)
+               return offset;
        switch (parents) {
        case 1:
                break;
@@ -393,6 +400,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
        int hdr = 1, body = 0;
        unsigned long offset = 0;
        int parents = 0;
+       int indent = (fmt == CMIT_FMT_ONELINE) ? 0 : 4;
 
        for (;;) {
                const char *line = msg;
@@ -416,7 +424,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
                if (hdr) {
                        if (linelen == 1) {
                                hdr = 0;
-                               buf[offset++] = '\n';
+                               if (fmt != CMIT_FMT_ONELINE)
+                                       buf[offset++] = '\n';
                                continue;
                        }
                        if (fmt == CMIT_FMT_RAW) {
@@ -446,13 +455,23 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
                } else {
                        body = 1;
                }
-               memset(buf + offset, ' ', 4);
-               memcpy(buf + offset + 4, line, linelen);
-               offset += linelen + 4;
+
+               memset(buf + offset, ' ', indent);
+               memcpy(buf + offset + indent, line, linelen);
+               offset += linelen + indent;
+               if (fmt == CMIT_FMT_ONELINE)
+                       break;
+       }
+       if (fmt == CMIT_FMT_ONELINE) {
+               /* We do not want the terminating newline */
+               if (buf[offset - 1] == '\n')
+                       offset--;
+       }
+       else {
+               /* Make sure there is an EOLN */
+               if (buf[offset - 1] != '\n')
+                       buf[offset++] = '\n';
        }
-       /* Make sure there is an EOLN */
-       if (buf[offset - 1] != '\n')
-               buf[offset++] = '\n';
        buf[offset] = '\0';
        return offset;
 }
index c24ab21..5d179d4 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -40,6 +40,7 @@ enum cmit_fmt {
        CMIT_FMT_DEFAULT = CMIT_FMT_MEDIUM,
        CMIT_FMT_SHORT,
        CMIT_FMT_FULL,
+       CMIT_FMT_ONELINE,
 };
 
 extern enum cmit_fmt get_commit_format(const char *arg);
index 20b80a1..a6657b1 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -166,7 +166,8 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
                        if (matched_src)
                                break;
                        errs = 1;
-                       error("src refspec %s does not match any.");
+                       error("src refspec %s does not match any.",
+                             rs[i].src);
                        break;
                default:
                        errs = 1;
@@ -381,8 +382,15 @@ int git_connect(int fd[2], char *url, const char *prog)
                close(pipefd[0][1]);
                close(pipefd[1][0]);
                close(pipefd[1][1]);
-               if (protocol == PROTO_SSH)
-                       execlp("ssh", "ssh", host, command, NULL);
+               if (protocol == PROTO_SSH) {
+                       const char *ssh = getenv("GIT_SSH") ? : "ssh";
+                       const char *ssh_basename = strrchr(ssh, '/');
+                       if (!ssh_basename)
+                               ssh_basename = ssh;
+                       else
+                               ssh_basename++;
+                       execlp(ssh, ssh_basename, host, command, NULL);
+               }
                else
                        execlp("sh", "sh", "-c", command, NULL);
                die("exec failed");
index 8916a36..95f0302 100644 (file)
@@ -60,7 +60,7 @@ static void convert_ascii_sha1(void *buffer)
        struct entry *entry;
 
        if (get_sha1_hex(buffer, sha1))
-               die("expected sha1, got '%s'", buffer);
+               die("expected sha1, got '%s'", (char*) buffer);
        entry = convert_entry(sha1);
        memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
 }
@@ -272,7 +272,7 @@ static void convert_commit(void *buffer, unsigned long size, unsigned char *resu
        unsigned long orig_size = size;
 
        if (memcmp(buffer, "tree ", 5))
-               die("Bad commit '%s'", buffer);
+               die("Bad commit '%s'", (char*) buffer);
        convert_ascii_sha1(buffer+5);
        buffer += 46;    /* "tree " + "hex sha1" + "\n" */
        while (!memcmp(buffer, "parent ", 7)) {
index 776cfb1..3ad1a99 100644 (file)
@@ -11,7 +11,7 @@ struct sha1file {
 };
 
 extern struct sha1file *sha1fd(int fd, const char *name);
-extern struct sha1file *sha1create(const char *fmt, ...);
+extern struct sha1file *sha1create(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern int sha1close(struct sha1file *, unsigned char *, int);
 extern int sha1write(struct sha1file *, void *, unsigned int);
 extern int sha1write_compressed(struct sha1file *, void *, unsigned int);
diff --git a/diff.c b/diff.c
index 9962fc3..3e52fec 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -134,8 +134,8 @@ static void builtin_diff(const char *name_a,
                         int complete_rewrite)
 {
        int i, next_at, cmd_size;
-       const char *diff_cmd = "diff -L%s%s -L%s%s";
-       const char *diff_arg  = "%s %s||:"; /* "||:" is to return 0 */
+       const char *const diff_cmd = "diff -L%s%s -L%s%s";
+       const char *const diff_arg  = "%s %s||:"; /* "||:" is to return 0 */
        const char *input_name_sq[2];
        const char *path0[2];
        const char *path1[2];
@@ -782,7 +782,8 @@ static void diff_flush_raw(struct diff_filepair *p,
        char status[10];
 
        if (line_termination) {
-               const char *err = "path %s cannot be expressed without -z";
+               const char *const err =
+                       "path %s cannot be expressed without -z";
                if (strchr(p->one->path, line_termination) ||
                    strchr(p->one->path, inter_name_termination))
                        die(err, p->one->path);
index f3bfbf3..e186363 100755 (executable)
@@ -3,7 +3,9 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-usage="usage: $0 "'<upstream> [<head>]
+. git-sh-setup-script || die "Not a git archive."
+
+usage="usage: $0 "'[-v] <upstream> [<head>]
 
              __*__*__*__*__> <upstream>
             /
@@ -18,29 +20,38 @@ upstream, it is shown on the standard output.
 The output is intended to be used as:
 
     OLD_HEAD=$(git-rev-parse HEAD)
-    git-rev-parse linus >${GIT_DIR-.}/HEAD
-    git-cherry linus OLD_HEAD |
+    git-rev-parse upstream >${GIT_DIR-.}/HEAD
+    git-cherry upstream $OLD_HEAD |
     while read commit
     do
         GIT_EXTERNAL_DIFF=git-apply-patch-script git-diff-tree -p "$commit" &&
-       git-commit-script -m "$commit"
+       git-commit-script -C "$commit"
     done
 '
 
+case "$1" in -v) verbose=t; shift ;; esac 
+
+case "$#,$1" in
+1,*..*)
+    upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
+    set x "$upstream" "$ours"
+    shift ;;
+esac
+
 case "$#" in
-1) linus=`git-rev-parse --verify "$1"` &&
-   junio=`git-rev-parse --verify HEAD` || exit
+1) upstream=`git-rev-parse --verify "$1"` &&
+   ours=`git-rev-parse --verify HEAD` || exit
    ;;
-2) linus=`git-rev-parse --verify "$1"` &&
-   junio=`git-rev-parse --verify "$2"` || exit
+2) upstream=`git-rev-parse --verify "$1"` &&
+   ours=`git-rev-parse --verify "$2"` || exit
    ;;
 *) echo >&2 "$usage"; exit 1 ;;
 esac
 
 # Note that these list commits in reverse order;
 # not that the order in inup matters...
-inup=`git-rev-list ^$junio $linus` &&
-ours=`git-rev-list $junio ^$linus` || exit
+inup=`git-rev-list ^$ours $upstream` &&
+ours=`git-rev-list $ours ^$upstream` || exit
 
 tmp=.cherry-tmp$$
 patch=$tmp-patch
@@ -74,6 +85,10 @@ do
                else
                        sign=+
                fi
+               case "$verbose" in
+               t)
+                       c=$(git-rev-list --pretty=oneline --max-count=1 $c)
+               esac
                case "$O" in
                '')     O="$sign $c" ;;
                *)      O="$sign $c$LF$O" ;;
index 1d59f46..24ec446 100755 (executable)
 . git-sh-setup-script || die "Not a git archive"
 
 usage () {
-       die 'git commit [--all] [-m existing-commit] [<path>...]'
+       die 'git commit [-a]  [-m <message>] [-F <logfile>] [(-C|-c) <commit>] [<path>...]'
 }
 
-files=()
-while case "$#" in 0) break ;; esac
+all= logfile= use_commit= no_edit= log_given= log_message=
+while case "$#" in 0) break;; esac
 do
-    case "$1" in
-    -m) shift
-        case "$#" in
-       0) usage ;;
-       *) use_commit=`git-rev-parse --verify "$1"` ||
-          exit ;;
-       esac
-       ;;
-    --all)
-       files=($(git-diff-files --name-only))\
-       ;;
-    *)  break
-        ;;
-    esac
+  case "$1" in
+  -a|--a|--al|--all)
+    all=t
+    shift ;;
+  -F=*|--f=*|--fi=*|--fil=*|--file=*)
+    log_given=t$log_given
+    logfile=`expr "$1" : '-[^=]*=\(.*\)'`
+    no_edit=t
+    shift ;;
+  -F|--f|--fi|--fil|--file)
+    case "$#" in 1) usage ;; esac; shift
+    log_given=t$log_given
+    logfile="$1"
+    no_edit=t
+    shift ;;
+  -m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+    log_given=t$log_given
+    log_message=`expr "$1" : '-[^=]*=\(.*\)'`
+    no_edit=t
+    shift ;;
+  -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+    case "$#" in 1) usage ;; esac; shift
+    log_given=t$log_given
+    log_message="$1"
+    no_edit=t
+    shift ;;
+  -c=*|--ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+  --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+  --reedit-messag=*|--reedit-message=*)
+    log_given=t$log_given
+    use_commit=`expr "$1" : '-[^=]*=\(.*\)'`
+    shift ;;
+  -c|--ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+  --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|--reedit-message)
+    case "$#" in 1) usage ;; esac; shift
+    log_given=t$log_given
+    use_commit="$1"
+    shift ;;
+  -C=*|--reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+  --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+  --reuse-message=*)
+    log_given=t$log_given
+    use_commit=`expr "$1" : '-[^=]*=\(.*\)'`
+    no_edit=t
+    shift ;;
+  -C|--reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+  --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+    case "$#" in 1) usage ;; esac; shift
+    log_given=t$log_given
+    use_commit="$1"
+    no_edit=t
+    shift ;;
+  --)
     shift
+    break ;;
+  -*)
+     usage ;;
+  *)
+    break ;;
+  esac
 done
 
-git-update-cache -q --refresh -- "$@" "${files[@]}" || exit 1
+case "$log_given" in
+tt*)
+  die "Only one of -c/-C/-F/-m can be used." ;;
+esac
+
+case "$all" in
+t)
+       git-diff-files --name-only -z |
+       xargs -0 git-update-cache -q -- || exit 1 ;;
+esac
+git-update-cache -q --refresh -- "$@" || exit 1
+
 PARENTS="-p HEAD"
 if [ ! -r "$GIT_DIR/HEAD" ]; then
        if [ -z "$(git-ls-files)" ]; then
                echo Nothing to commit 1>&2
                exit 1
        fi
-       (
+       {
                echo "#"
                echo "# Initial commit"
+               case "$no_edit" in
+               t) echo "# (ignoring your commit message for initial commit)"
+                  no_edit= 
+               esac
                echo "#"
                git-ls-files | sed 's/^/# New file: /'
                echo "#"
-       ) > .editmsg
+       } >.editmsg
        PARENTS=""
+       no_edit=
 else
        if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
                echo "#"
@@ -51,8 +112,25 @@ else
                echo "# If this is not correct, please remove the file"
                echo "# $GIT_DIR/MERGE_HEAD"
                echo "# and try again"
+               case "$no_edit" in
+               t) echo "# (ignoring your commit message for merge commit)"
+                  no_edit= 
+               esac
                echo "#"
                PARENTS="-p HEAD -p MERGE_HEAD"
+       elif test "$log_message" != ''
+       then
+               echo "$log_message"
+       elif test "$logfile" != ""
+       then
+               if test "$logfile" = -
+               then
+                       test -t 0 &&
+                       echo >&2 "(reading log message from standard input)"
+                       cat
+               else
+                       cat <"$logfile"
+               fi
        elif test "$use_commit" != ""
        then
                pick_author_script='
@@ -92,17 +170,22 @@ then
        rm .editmsg
        exit 1
 fi
-case "$use_commit" in
+case "$no_edit" in
 '')
        ${VISUAL:-${EDITOR:-vi}} .editmsg
        ;;
 esac
 grep -v '^#' < .editmsg | git-stripspace > .cmitmsg
-[ -s .cmitmsg ] && 
+if test -s .cmitmsg
+then
        tree=$(git-write-tree) &&
        commit=$(cat .cmitmsg | git-commit-tree $tree $PARENTS) &&
        echo $commit > "$GIT_DIR/HEAD" &&
        rm -f -- "$GIT_DIR/MERGE_HEAD"
+else
+       echo >&2 "* no commit message?  aborting commit."
+       false
+fi
 ret="$?"
 rm -f .cmitmsg .editmsg
 exit "$ret"
index 51e8af0..c008169 100755 (executable)
@@ -3,6 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
+. git-sh-setup-script || die "Not a git archive."
+
 usage () {
     echo >&2 "usage: $0"' [-n] [-o dir] [--mbox] [--check] [-<diff options>...] upstream [ our-head ]
 
@@ -60,13 +62,20 @@ do
     shift
 done
 
+revpair=
 case "$#" in
-2)    linus="$1" junio="$2" ;;
-1)    linus="$1" junio=HEAD ;;
-*)    usage ;;
+2)
+    revpair="$1..$2" ;;
+1)
+    case "$1" in
+    *..*)
+       revpair="$1";;
+    *)
+       revpair="$1..HEAD";;
+    esac ;;
+*)
+    usage ;;
 esac
-junio=`git-rev-parse --verify "$junio"`
-linus=`git-rev-parse --verify "$linus"`
 
 me=`git-var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'`
 
@@ -108,7 +117,8 @@ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
 stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
 
-git-rev-list --merge-order "$junio" "^$linus" >$series
+git-rev-list --no-merges --merge-order \
+       $(git-rev-parse --revs-only "$revpair") >$series
 total=`wc -l <$series | tr -dc "[0-9]"`
 i=$total
 while read commit
index 31cdac8..75f6027 100755 (executable)
@@ -3,7 +3,7 @@
 . git-sh-setup-script || die "Not a git archive"
 
 usage () {
-    echo >&2 "usage: $0 [--heads] [--tags] [--overwrite | --store] repo"
+    echo >&2 "usage: $0 [--heads] [--tags] <repository> <refs>..."
     exit 1;
 }
 
@@ -12,10 +12,6 @@ do
   case "$1" in
   -h|--h|--he|--hea|--head|--heads)
   heads=heads; shift ;;
-  -o|--o|--ov|--ove|--over|--overw|--overwr|--overwri|--overwrit|--overwrite)
-  overwrite=overwrite; shift ;;
-  -s|--s|--st|--sto|--stor|--store)
-  store=store; shift ;;
   -t|--t|--ta|--tag|--tags)
   tags=tags; shift ;;
   --)
@@ -27,15 +23,15 @@ do
   esac
 done
 
-case "$#" in 1) ;; *) usage ;; esac
-case ",$store,$overwrite," in *,,*) ;; *) usage ;; esac
+case "$#" in 0) usage ;; esac
 
 case ",$heads,$tags," in
 ,,,) heads=heads tags=tags other=other ;;
 esac
 
-. git-parse-remote "$@"
+. git-parse-remote "$1"
 peek_repo="$_remote_repo"
+shift
 
 tmp=.ls-remote-$$
 trap "rm -fr $tmp-*" 0 1 2 3 15
@@ -65,7 +61,7 @@ rsync://* )
        git-peek-remote "$peek_repo"
        ;;
 esac |
-
+sort -t '      ' -k 2 |
 while read sha1 path
 do
        case "$path" in
@@ -82,23 +78,23 @@ do
        *)
                continue;;
        esac
-
-       echo "$sha1     $path"
-
-       case "$path,$store,$overwrite," in
-       *,,, | HEAD,*) continue ;;
+       case "$#" in
+       0)
+               match=yes ;;
+       *)
+               match=no
+               for pat
+               do
+                       case "/$path" in
+                       */$pat )
+                               match=yes
+                               break ;;
+                       esac
+               done
        esac
-
-       if test -f "$GIT_DIR/$path" && test "$overwrite" == ""
-       then
-               continue
-       fi
-
-       # Be careful.  We may not have that object yet!
-       if git-cat-file -t "$sha1" >/dev/null 2>&1
-       then
-               echo "$sha1" >"$GIT_DIR/$path"
-       else
-               echo >&2 "* You have not fetched updated $path ($sha1)."
-       fi
+       case "$match" in
+       no)
+               continue ;;
+       esac
+       echo "$sha1     $path"
 done
index 80e922b..70fa968 100755 (executable)
@@ -1,3 +1,64 @@
 #!/bin/sh
 . git-sh-setup-script || die "Not a git archive"
-git-send-pack "$@"
+
+# Parse out parameters and then stop at remote, so that we can
+# translate it using .git/branches information
+has_all=
+has_force=
+has_exec=
+remote=
+
+while case "$#" in 0) break ;; esac
+do
+       case "$1" in
+       --all)
+               has_all=--all ;;
+       --force)
+               has_force=--force ;;
+       --exec=*)
+               has_exec="$1" ;;
+       -*)
+               die "Unknown parameter $1" ;;
+        *)
+               remote="$1"
+               shift
+               set x "$@"
+               shift
+               break ;;
+       esac
+       shift
+done
+
+case "$remote" in
+*:* | /* | ../* | ./* )
+       # An URL, host:/path/to/git, absolute and relative paths.
+       ;;
+* )
+       # Shorthand
+       if expr "$remote" : '..*/..*' >/dev/null
+       then
+               # a short-hand followed by a trailing path
+               shorthand=$(expr "$remote" : '\([^/]*\)')
+               remainder=$(expr "$remote" : '[^/]*\(/.*\)$')
+       else
+               shorthand="$remote"
+               remainder=
+       fi
+       remote=$(sed -e 's/#.*//' "$GIT_DIR/branches/$remote") &&
+       expr "$remote" : '..*:' >/dev/null &&
+       remote="$remote$remainder" ||
+       die "Cannot parse remote $remote"
+       ;;
+esac
+
+case "$remote" in
+http://* | https://* | git://* | rsync://* )
+       die "Cannot push to $remote" ;;
+esac
+
+set x "$remote" "$@"; shift
+test "$has_all" && set x "$has_all" "$@" && shift
+test "$has_force" && set x "$has_force" "$@" && shift
+test "$has_exec" && set x "$has_exec" "$@" && shift
+
+exec git-send-pack "$@"
index 5b791c6..7779813 100755 (executable)
@@ -3,25 +3,32 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
+. git-sh-setup-script || die "Not a git archive."
+
 usage="usage: $0 "'<upstream> [<head>]
 
 Uses output from git-cherry to rebase local commits to the new head of
 upstream tree.'
 
-: ${GIT_DIR=.git}
+case "$#,$1" in
+1,*..*)
+    upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
+    set x "$upstream" "$ours"
+    shift ;;
+esac
 
 case "$#" in
-1) linus=`git-rev-parse --verify "$1"` &&
-   junio=`git-rev-parse --verify HEAD` || exit
+1) upstream=`git-rev-parse --verify "$1"` &&
+   ours=`git-rev-parse --verify HEAD` || exit
    ;;
-2) linus=`git-rev-parse --verify "$1"` &&
-   junio=`git-rev-parse --verify "$2"` || exit
+2) upstream=`git-rev-parse --verify "$1"` &&
+   ours=`git-rev-parse --verify "$2"` || exit
    ;;
 *) echo >&2 "$usage"; exit 1 ;;
 esac
 
-git-read-tree -m -u $junio $linus &&
-echo "$linus" >"$GIT_DIR/HEAD" || exit
+git-read-tree -m -u $ours $upstream &&
+echo "$upstream" >"$GIT_DIR/HEAD" || exit
 
 tmp=.rebase-tmp$$
 fail=$tmp-fail
@@ -29,7 +36,7 @@ trap "rm -rf $tmp-*" 0 1 2 3 15
 
 >$fail
 
-git-cherry $linus $junio |
+git-cherry $upstream $ours |
 while read sign commit
 do
        case "$sign" in
@@ -37,7 +44,7 @@ do
        esac
        S=`cat "$GIT_DIR/HEAD"` &&
         GIT_EXTERNAL_DIFF=git-apply-patch-script git-diff-tree -p $commit &&
-       git-commit-script -m "$commit" || {
+       git-commit-script -C "$commit" || {
                echo $commit >>$fail
                git-read-tree --reset -u $S
        }
index b6476ed..49994df 100755 (executable)
@@ -2,6 +2,12 @@
 . git-sh-setup-script || die "Not a git archive"
 rev=$(git-rev-parse --revs-only --verify --default HEAD "$@") || exit
 rev=$(git-rev-parse --revs-only --verify $rev^0) || exit
-git-read-tree --reset "$rev" && echo "$rev" > "$GIT_DIR/HEAD"
+git-read-tree --reset "$rev" && {
+       if orig=$(git-rev-parse --verify HEAD 2>/dev/null)
+       then
+               echo "$orig" >"$GIT_DIR/ORIG_HEAD"
+       fi
+       echo "$rev" > "$GIT_DIR/HEAD"
+}
 git-update-cache --refresh
 rm -f "$GIT_DIR/MERGE_HEAD"
diff --git a/git-revert-script b/git-revert-script
new file mode 100755 (executable)
index 0000000..dc2dea4
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+. git-sh-setup-script || die "Not a git archive"
+
+# We want a clean tree and clean index to be able to revert.
+status=$(git status)
+case "$status" in
+'nothing to commit') ;;
+*)
+       echo "$status"
+       die "Your working tree is dirty; cannot revert a previous patch." ;;
+esac
+
+rev=$(git-rev-parse --no-flags --verify --revs-only "$@") &&
+commit=$(git-rev-parse --verify "$rev^0") || exit
+if git-diff-tree -R -M -p $commit | git-apply --index &&
+   msg=$(git-rev-list --pretty=oneline --max-count=1 $commit)
+then
+        {
+                echo "$msg" | sed -e '
+                       s/^[^ ]* /Revert "/
+                       s/$/"/'
+                echo
+                echo "This reverts $commit commit."
+                test "$rev" = "$commit" ||
+                echo "(original 'git revert' arguments: $@)"
+        } | git commit -F -
+else
+        # Now why did it fail?
+        parents=`git-cat-file commit "$commit" 2>/dev/null |
+                sed -ne '/^$/q;/^parent /p' |
+                wc -l`
+        case $parents in
+        0) die "Cannot revert the root commit nor non commit-ish." ;;
+        1) die "The patch does not apply." ;;
+        *) die "Cannot revert a merge commit." ;;
+        esac
+fi
index 054b013..511f294 100644 (file)
@@ -15,7 +15,7 @@ static int verify_packfile(struct packed_git *p)
        /* Header consistency check */
        hdr = p->pack_base;
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
-               return error("Packfile signature mismatch", p->pack_name);
+               return error("Packfile %s signature mismatch", p->pack_name);
        if (hdr->hdr_version != htonl(PACK_VERSION))
                return error("Packfile version %d different from ours %d",
                             ntohl(hdr->hdr_version), PACK_VERSION);
index b0b4f6d..51d0cbe 100644 (file)
@@ -5,7 +5,7 @@
  * Silly packetized line writing interface
  */
 void packet_flush(int fd);
-void packet_write(int fd, const char *fmt, ...);
+void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
 
 int packet_read_line(int fd, char *buffer, unsigned size);
 
diff --git a/refs.c b/refs.c
index 774f163..a5c8946 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -6,7 +6,7 @@
 static int read_ref(const char *refname, unsigned char *sha1)
 {
        int ret = -1;
-       int fd = open(git_path(refname), O_RDONLY);
+       int fd = open(git_path("%s", refname), O_RDONLY);
 
        if (fd >= 0) {
                char buffer[60];
@@ -20,7 +20,7 @@ static int read_ref(const char *refname, unsigned char *sha1)
 static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1))
 {
        int retval = 0;
-       DIR *dir = opendir(git_path(base));
+       DIR *dir = opendir(git_path("%s", base));
 
        if (dir) {
                struct dirent *de;
@@ -46,7 +46,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u
                        if (namelen > 255)
                                continue;
                        memcpy(path + baselen, de->d_name, namelen+1);
-                       if (lstat(git_path(path), &st) < 0)
+                       if (lstat(git_path("%s", path), &st) < 0)
                                continue;
                        if (S_ISDIR(st.st_mode)) {
                                retval = do_for_each_ref(path, fn);
index fae30a2..ce5b8b2 100644 (file)
@@ -15,12 +15,15 @@ static const char rev_list_usage[] =
                      "  --max-count=nr\n"
                      "  --max-age=epoch\n"
                      "  --min-age=epoch\n"
+                     "  --parents\n"
                      "  --bisect\n"
                      "  --objects\n"
                      "  --unpacked\n"
                      "  --header\n"
                      "  --pretty\n"
-                     "  --merge-order [ --show-breaks ]";
+                     "  --no-merges\n"
+                     "  --merge-order [ --show-breaks ]\n"
+                     "  --topo-order";
 
 static int unpacked = 0;
 static int bisect_list = 0;
@@ -39,6 +42,7 @@ static int merge_order = 0;
 static int show_breaks = 0;
 static int stop_traversal = 0;
 static int topo_order = 0;
+static int no_merges = 0;
 
 static void show_commit(struct commit *commit)
 {
@@ -59,7 +63,11 @@ static void show_commit(struct commit *commit)
                        parents = parents->next;
                }
        }
-       putchar('\n');
+       if (commit_format == CMIT_FMT_ONELINE)
+               putchar(' ');
+       else
+               putchar('\n');
+
        if (verbose_header) {
                static char pretty_header[16384];
                pretty_print_commit(commit_format, commit->buffer, ~0, pretty_header, sizeof(pretty_header));
@@ -82,6 +90,8 @@ static int filter_commit(struct commit * commit)
        }
        if (max_count != -1 && !max_count--)
                return STOP;
+       if (no_merges && (commit->parents && commit->parents->next))
+               return CONTINUE;
        return DO;
 }
 
@@ -497,7 +507,14 @@ int main(int argc, char **argv)
                        commit_format = get_commit_format(arg+8);
                        verbose_header = 1;
                        hdr_termination = '\n';
-                       prefix = "commit ";
+                       if (commit_format == CMIT_FMT_ONELINE)
+                               prefix = "";
+                       else
+                               prefix = "commit ";
+                       continue;
+               }
+               if (!strncmp(arg, "--no-merges", 11)) {
+                       no_merges = 1;
                        continue;
                }
                if (!strcmp(arg, "--parents")) {
index 1965e90..1c6ae76 100644 (file)
@@ -33,6 +33,9 @@ static int is_rev_argument(const char *arg)
                "--max-age=",
                "--min-age=",
                "--merge-order",
+               "--topo-order",
+               "--bisect",
+               "--no-merges",
                NULL
        };
        const char **p = rev_args;
diff --git a/rsh.c b/rsh.c
index fe87e58..bcb1c80 100644 (file)
--- a/rsh.c
+++ b/rsh.c
@@ -56,10 +56,16 @@ int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
                return error("Couldn't create socket");
        }
        if (!fork()) {
+               const char *ssh = getenv("GIT_SSH") ? : "ssh";
+               const char *ssh_basename = strrchr(ssh, '/');
+               if (!ssh_basename)
+                       ssh_basename = ssh;
+               else
+                       ssh_basename++;
                close(sv[1]);
                dup2(sv[0], 0);
                dup2(sv[0], 1);
-               execlp("ssh", "ssh", host, command, NULL);
+               execlp(ssh, ssh_basename, host, command, NULL);
        }
        close(sv[0]);
        *fd_in = sv[1];
index e9285c1..8d189d4 100644 (file)
@@ -1388,7 +1388,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
                ssize_t size;
                if (*bufposn) {
                        stream.avail_in = *bufposn;
-                       stream.next_in = buffer;
+                       stream.next_in = (unsigned char *) buffer;
                        do {
                                stream.next_out = discard;
                                stream.avail_out = sizeof(discard);
index a877fe5..2716ae3 100644 (file)
@@ -325,8 +325,8 @@ static void write_header(const unsigned char *sha1, char typeflag, const char *b
        memcpy(&header[257], "ustar", 6);
        memcpy(&header[263], "00", 2);
 
-       printf(&header[329], "%07o", 0);        /* devmajor */
-       printf(&header[337], "%07o", 0);        /* devminor */
+       sprintf(&header[329], "%07o", 0);       /* devmajor */
+       sprintf(&header[337], "%07o", 0);       /* devminor */
 
        memset(&header[148], ' ', 8);
        for (i = 0; i < RECORDSIZE; i++)
index 7b71208..a3238c2 100644 (file)
@@ -77,7 +77,7 @@ static int parse_email(const void *map, unsigned long size)
 
        /*
         * Search for a line beginning with "From ", and 
-        * having smething that looks like a date format.
+        * having something that looks like a date format.
         */
        do {
                int len = linelen(map, size);