Merge branch 'js/reflog'
authorJunio C Hamano <junkio@cox.net>
Wed, 10 Jan 2007 22:16:16 +0000 (14:16 -0800)
committerJunio C Hamano <junkio@cox.net>
Wed, 10 Jan 2007 22:16:16 +0000 (14:16 -0800)
* js/reflog:
Sanitize for_each_reflog_ent()

25 files changed:
Documentation/git-applymbox.txt
Documentation/git-init.txt [new file with mode: 0644]
Documentation/git-mailinfo.txt
Documentation/git-svn.txt
Makefile
builtin-apply.c
builtin-archive.c
builtin-describe.c [new file with mode: 0644]
builtin-mailinfo.c
builtin.h
compat/pread.c [new file with mode: 0644]
contrib/emacs/git.el
describe.c [deleted file]
git-am.sh
git-applymbox.sh
git-clone.sh
git-compat-util.h
git-send-email.perl
git.c
gitweb/gitweb.perl
http-fetch.c
http-push.c
sha1_file.c
t/t1410-reflog.sh
tree-walk.c
index f74c6a49b3c5d52ed662a83832c7d06915fac65b..95dc65a583552d4f7e2d1fa34c448832c66a3353 100644 (file)
@@ -42,13 +42,13 @@ OPTIONS
        and the current tree.
 
 -u::
-       By default, the commit log message, author name and
-       author email are taken from the e-mail without any
-       charset conversion, after minimally decoding MIME
-       transfer encoding.  This flag causes the resulting
-       commit to be encoded in utf-8 by transliterating them.
-       Note that the patch is always used as is without charset
-       conversion, even with this flag.
+       The commit log message, author name and author email are
+       taken from the e-mail, and after minimally decoding MIME
+       transfer encoding, re-coded in UTF-8 by transliterating
+       them.  This used to be optional but now it is the default.
++
+Note that the patch is always used as-is without charset
+conversion, even with this flag.
 
 -c .dotest/<num>::
        When the patch contained in an e-mail does not cleanly
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
new file mode 100644 (file)
index 0000000..36838c7
--- /dev/null
@@ -0,0 +1 @@
+include::git-init-db.txt[]
index ea0a06557f933ce48374ddbb751a64945ff65955..5088bbea84c0e6b681641b78b816755fa12f6b6d 100644 (file)
@@ -33,15 +33,13 @@ OPTIONS
        format-patch --mbox' output.
 
 -u::
-       By default, the commit log message, author name and
-       author email are taken from the e-mail without any
-       charset conversion, after minimally decoding MIME
-       transfer encoding.  This flag causes the resulting
-       commit to be encoded in the encoding specified by
-       i18n.commitencoding configuration (defaults to utf-8) by
-       transliterating them. 
-       Note that the patch is always used as is without charset
-       conversion, even with this flag.
+       The commit log message, author name and author email are
+       taken from the e-mail, and after minimally decoding MIME
+       transfer encoding, re-coded in UTF-8 by transliterating
+       them.  This used to be optional but now it is the default.
++
+Note that the patch is always used as-is without charset
+conversion, even with this flag.
 
 --encoding=<encoding>::
        Similar to -u but if the local convention is different
index 8df43cb819770fe8540bc392bede53ba16070831..1b013139af0359458c7abae2a12c8da608041849 100644 (file)
@@ -249,8 +249,7 @@ repo-config key: svn.authorsfile
 
 -q::
 --quiet::
-       Make git-svn less verbose.  This only affects git-svn if you
-       have the SVN::* libraries installed and are using them.
+       Make git-svn less verbose.
 
 --repack[=<n>]::
 --repack-flags=<flags>
@@ -321,8 +320,6 @@ for more information on using GIT_SVN_ID.
        started tracking a branch and never tracked the trunk it was
        descended from.
 
-       This relies on the SVN::* libraries to work.
-
 repo-config key: svn.followparent
 
 --no-metadata::
@@ -350,25 +347,6 @@ Run this if you used an old version of git-svn that used
 "git-svn-HEAD" instead of "remotes/git-svn" as the branch
 for tracking the remote.
 
---no-ignore-externals::
-Only used with the 'fetch' and 'rebuild' command.
-
-This command has no effect when you are using the SVN::*
-libraries with git, svn:externals are always avoided.
-
-By default, git-svn passes --ignore-externals to svn to avoid
-fetching svn:external trees into git.  Pass this flag to enable
-externals tracking directly via git.
-
-Versions of svn that do not support --ignore-externals are
-automatically detected and this flag will be automatically
-enabled for them.
-
-Otherwise, do not enable this flag unless you know what you're
-doing.
-
-repo-config key: svn.noignoreexternals
-
 --ignore-nodate::
 Only used with the 'fetch' command.
 
@@ -486,49 +464,18 @@ This allows you to tie unfetched SVN revision 375 to your current HEAD:
        git-svn fetch 375=$(git-rev-parse HEAD)
 ------------------------------------------------
 
-Advanced Example: Tracking a Reorganized Repository
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Note: this example is now obsolete if you have SVN::* libraries
-installed.  Simply use --follow-parent when fetching.
-
 If you're tracking a directory that has moved, or otherwise been
 branched or tagged off of another directory in the repository and you
-care about the full history of the project, then you can read this
-section.
-
-This is how Yann Dirson tracked the trunk of the ufoai directory when
-the /trunk directory of his repository was moved to /ufoai/trunk and
-he needed to continue tracking /ufoai/trunk where /trunk left off.
+care about the full history of the project, then you can use
+the --follow-parent option.
 
-------------------------------------------------------------------------
-       # This log message shows when the repository was reorganized:
-       r166 | ydirson | 2006-03-02 01:36:55 +0100 (Thu, 02 Mar 2006) | 1 line
-       Changed paths:
-          D /trunk
-          A /ufoai/trunk (from /trunk:165)
-
-       # First we start tracking the old revisions:
-       GIT_SVN_ID=git-oldsvn git-svn init \
-                       https://svn.sourceforge.net/svnroot/ufoai/trunk
-       GIT_SVN_ID=git-oldsvn git-svn fetch -r1:165
-
-       # And now, we continue tracking the new revisions:
-       GIT_SVN_ID=git-newsvn git-svn init \
-             https://svn.sourceforge.net/svnroot/ufoai/ufoai/trunk
-       GIT_SVN_ID=git-newsvn git-svn fetch \
-             166=`git-rev-parse refs/remotes/git-oldsvn`
-------------------------------------------------------------------------
+------------------------------------------------
+       git-svn fetch --follow-parent
+------------------------------------------------
 
 BUGS
 ----
 
-If you are not using the SVN::* Perl libraries and somebody commits a
-conflicting changeset to SVN at a bad moment (right before you commit)
-causing a conflict and your commit to fail, your svn working tree
-($GIT_DIR/git-svn/tree) may be dirtied.  The easiest thing to do is
-probably just to rm -rf $GIT_DIR/git-svn/tree and run 'rebuild'.   You
-can avoid this problem entirely by using 'dcommit'.
-
 We ignore all SVN properties except svn:executable.  Too difficult to
 map them since we rely heavily on git write-tree being _exactly_ the
 same on both the SVN and git working trees and I prefer not to clutter
index 6c12bc64ac9da2bb9fafd2a6a88053dc82b7d6d3..8432ab8ba1c69f1269808782b17e62ce92460b4e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 # The default target of this Makefile is...
-all:
+all::
 
 # Define NO_OPENSSL environment variable if you do not have OpenSSL.
 # This also implies MOZILLA_SHA1.
@@ -69,6 +69,9 @@ all:
 #
 # Define NO_MMAP if you want to avoid mmap.
 #
+# Define NO_PREAD if you have a problem with pread() system call (e.g.
+# cygwin.dll before v1.5.22).
+#
 # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
 # generally faster on your platform than accessing the working directory.
 #
@@ -201,7 +204,7 @@ PROGRAMS = \
        git-update-server-info$X \
        git-upload-pack$X git-verify-pack$X \
        git-pack-redundant$X git-var$X \
-       git-describe$X git-merge-tree$X git-imap-send$X \
+       git-merge-tree$X git-imap-send$X \
        git-merge-recursive$X \
        $(EXTRA_PROGRAMS)
 
@@ -272,6 +275,7 @@ BUILTIN_OBJS = \
        builtin-check-ref-format.o \
        builtin-commit-tree.o \
        builtin-count-objects.o \
+       builtin-describe.o \
        builtin-diff.o \
        builtin-diff-files.o \
        builtin-diff-index.o \
@@ -523,6 +527,10 @@ ifdef NO_MMAP
        COMPAT_CFLAGS += -DNO_MMAP
        COMPAT_OBJS += compat/mmap.o
 endif
+ifdef NO_PREAD
+       COMPAT_CFLAGS += -DNO_PREAD
+       COMPAT_OBJS += compat/pread.o
+endif
 ifdef NO_FAST_WORKING_DIRECTORY
        BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
 endif
@@ -597,9 +605,12 @@ export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir
 
 ### Build rules
 
-all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk gitweb/gitweb.cgi
+all:: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk gitweb/gitweb.cgi
+ifneq (,$X)
+       $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), rm -f '$p';)
+endif
 
-all:
+all::
        $(MAKE) -C perl PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all
        $(MAKE) -C templates
 
@@ -841,6 +852,9 @@ install: all
                        '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \
        fi
        $(foreach p,$(BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
+ifneq (,$X)
+       $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';)
+endif
 
 install-doc:
        $(MAKE) -C Documentation install
index 1c3583706835339d2f3a0b0a5d3b989aae2a8142..54fd2cb0c71dc97a47d0286d7b201545a7308b01 100644 (file)
@@ -811,7 +811,8 @@ 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, (int)len-1, line);
+                       die("patch fragment without header at line %d: %.*s",
+                           linenr, (int)len-1, line);
                }
 
                if (size < len + 6)
@@ -2238,8 +2239,19 @@ static void remove_file(struct patch *patch)
                        die("unable to remove %s from index", patch->old_name);
                cache_tree_invalidate_path(active_cache_tree, patch->old_name);
        }
-       if (!cached)
-               unlink(patch->old_name);
+       if (!cached) {
+               if (!unlink(patch->old_name)) {
+                       char *name = xstrdup(patch->old_name);
+                       char *end = strrchr(name, '/');
+                       while (end) {
+                               *end = 0;
+                               if (rmdir(name))
+                                       break;
+                               end = strrchr(name, '/');
+                       }
+                       free(name);
+               }
+       }
 }
 
 static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)
index 391cf43911a16ec49862c18b7dd4f1f094d49de8..32737d31621e8d1a900d944f97fcaae43d56a12e 100644 (file)
@@ -137,7 +137,6 @@ void parse_treeish_arg(const char **argv, struct archiver_args *ar_args,
                if (err || !S_ISDIR(mode))
                        die("current working directory is untracked");
 
-               free(tree);
                tree = parse_tree_indirect(tree_sha1);
        }
        ar_args->tree = tree;
diff --git a/builtin-describe.c b/builtin-describe.c
new file mode 100644 (file)
index 0000000..ad3b469
--- /dev/null
@@ -0,0 +1,176 @@
+#include "cache.h"
+#include "commit.h"
+#include "tag.h"
+#include "refs.h"
+#include "builtin.h"
+
+#define SEEN (1u << 0)
+
+static const char describe_usage[] =
+"git-describe [--all] [--tags] [--abbrev=<n>] <committish>*";
+
+static int all;        /* Default to annotated tags only */
+static int tags;       /* But allow any tags if --tags is specified */
+
+static int abbrev = DEFAULT_ABBREV;
+
+static int names, allocs;
+static struct commit_name {
+       const struct commit *commit;
+       int prio; /* annotated tag = 2, tag = 1, head = 0 */
+       char path[FLEX_ARRAY]; /* more */
+} **name_array = NULL;
+
+static struct commit_name *match(struct commit *cmit)
+{
+       int i = names;
+       struct commit_name **p = name_array;
+
+       while (i-- > 0) {
+               struct commit_name *n = *p++;
+               if (n->commit == cmit)
+                       return n;
+       }
+       return NULL;
+}
+
+static void add_to_known_names(const char *path,
+                              const struct commit *commit,
+                              int prio)
+{
+       int idx;
+       int len = strlen(path)+1;
+       struct commit_name *name = xmalloc(sizeof(struct commit_name) + len);
+
+       name->commit = commit;
+       name->prio = prio;
+       memcpy(name->path, path, len);
+       idx = names;
+       if (idx >= allocs) {
+               allocs = (idx + 50) * 3 / 2;
+               name_array = xrealloc(name_array, allocs*sizeof(*name_array));
+       }
+       name_array[idx] = name;
+       names = ++idx;
+}
+
+static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+{
+       struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+       struct object *object;
+       int prio;
+
+       if (!commit)
+               return 0;
+       object = parse_object(sha1);
+       /* If --all, then any refs are used.
+        * If --tags, then any tags are used.
+        * Otherwise only annotated tags are used.
+        */
+       if (!strncmp(path, "refs/tags/", 10)) {
+               if (object->type == OBJ_TAG)
+                       prio = 2;
+               else
+                       prio = 1;
+       }
+       else
+               prio = 0;
+
+       if (!all) {
+               if (!prio)
+                       return 0;
+               if (!tags && prio < 2)
+                       return 0;
+       }
+       add_to_known_names(all ? path + 5 : path + 10, commit, prio);
+       return 0;
+}
+
+static int compare_names(const void *_a, const void *_b)
+{
+       struct commit_name *a = *(struct commit_name **)_a;
+       struct commit_name *b = *(struct commit_name **)_b;
+       unsigned long a_date = a->commit->date;
+       unsigned long b_date = b->commit->date;
+
+       if (a->prio != b->prio)
+               return b->prio - a->prio;
+       return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
+}
+
+static void describe(const char *arg, int last_one)
+{
+       unsigned char sha1[20];
+       struct commit *cmit;
+       struct commit_list *list;
+       static int initialized = 0;
+       struct commit_name *n;
+
+       if (get_sha1(arg, sha1))
+               die("Not a valid object name %s", arg);
+       cmit = lookup_commit_reference(sha1);
+       if (!cmit)
+               die("%s is not a valid '%s' object", arg, commit_type);
+
+       if (!initialized) {
+               initialized = 1;
+               for_each_ref(get_name, NULL);
+               qsort(name_array, names, sizeof(*name_array), compare_names);
+       }
+
+       n = match(cmit);
+       if (n) {
+               printf("%s\n", n->path);
+               return;
+       }
+
+       list = NULL;
+       commit_list_insert(cmit, &list);
+       while (list) {
+               struct commit *c = pop_most_recent_commit(&list, SEEN);
+               n = match(c);
+               if (n) {
+                       printf("%s-g%s\n", n->path,
+                              find_unique_abbrev(cmit->object.sha1, abbrev));
+                       if (!last_one)
+                               clear_commit_marks(cmit, SEEN);
+                       return;
+               }
+       }
+       die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1));
+}
+
+int cmd_describe(int argc, const char **argv, const char *prefix)
+{
+       int i;
+
+       for (i = 1; i < argc; i++) {
+               const char *arg = argv[i];
+
+               if (*arg != '-')
+                       break;
+               else if (!strcmp(arg, "--all"))
+                       all = 1;
+               else if (!strcmp(arg, "--tags"))
+                       tags = 1;
+               else if (!strncmp(arg, "--abbrev=", 9)) {
+                       abbrev = strtoul(arg + 9, NULL, 10);
+                       if (abbrev < MINIMUM_ABBREV || 40 < abbrev)
+                               abbrev = DEFAULT_ABBREV;
+               }
+               else
+                       usage(describe_usage);
+       }
+
+       save_commit_buffer = 0;
+
+       if (argc <= i)
+               describe("HEAD", 1);
+       else
+               while (i < argc) {
+                       describe(argv[i], (i == argc - 1));
+                       i++;
+               }
+
+       return 0;
+}
index a67f3eb90b6f715714c6fa7bb931044630c74111..583da38b6750185eb38f04d91555aa75ee4a77b0 100644 (file)
@@ -515,12 +515,9 @@ static void convert_to_utf8(char *line, char *charset)
        char *input_charset = *charset ? charset : latin_one;
        char *out = reencode_string(line, metainfo_charset, input_charset);
 
-       if (!out) {
-               fprintf(stderr, "cannot convert from %s to %s\n",
-                       input_charset, metainfo_charset);
-               *charset = 0;
-               return;
-       }
+       if (!out)
+               die("cannot convert from %s to %s\n",
+                   input_charset, metainfo_charset);
        strcpy(line, out);
        free(out);
 }
@@ -797,17 +794,23 @@ static const char mailinfo_usage[] =
 
 int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
+       const char *def_charset;
+
        /* NEEDSWORK: might want to do the optional .git/ directory
         * discovery
         */
        git_config(git_default_config);
 
+       def_charset = (git_commit_encoding ? git_commit_encoding : "utf-8");
+       metainfo_charset = def_charset;
+
        while (1 < argc && argv[1][0] == '-') {
                if (!strcmp(argv[1], "-k"))
                        keep_subject = 1;
                else if (!strcmp(argv[1], "-u"))
-                       metainfo_charset = (git_commit_encoding
-                                           ? git_commit_encoding : "utf-8");
+                       metainfo_charset = def_charset;
+               else if (!strcmp(argv[1], "-n"))
+                       metainfo_charset = NULL;
                else if (!strncmp(argv[1], "--encoding=", 11))
                        metainfo_charset = argv[1] + 11;
                else
index df72d09447d0edd17d07eb97a9b3b36fa4b57531..0b3c9f62efed895bcfebe31f1164ac991ee01d41 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -25,6 +25,7 @@ extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
 extern int cmd_cherry(int argc, const char **argv, const char *prefix);
 extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_describe(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
 extern int cmd_diff(int argc, const char **argv, const char *prefix);
diff --git a/compat/pread.c b/compat/pread.c
new file mode 100644 (file)
index 0000000..978cac4
--- /dev/null
@@ -0,0 +1,18 @@
+#include "../git-compat-util.h"
+
+ssize_t git_pread(int fd, void *buf, size_t count, off_t offset)
+{
+        off_t current_offset;
+        ssize_t rc;
+
+        current_offset = lseek(fd, 0, SEEK_CUR);
+
+        if (lseek(fd, offset, SEEK_SET) < 0)
+                return -1;
+
+        rc = read_in_full(fd, buf, count);
+
+        if (current_offset != lseek(fd, current_offset, SEEK_SET))
+                return -1;
+        return rc;
+}
index ede3ab2bd8bd77f9bf110f83bb0dfb9688634aef..d90ba816e0521ccc0ee20592cbea3fad74fcb1a3 100644 (file)
@@ -280,6 +280,15 @@ and returns the process output as a string."
     (git-run-command nil nil "update-index" "--info-only" "--add" "--" (file-relative-name ignore-name)))
   (git-add-status-file (if created 'added 'modified) (file-relative-name ignore-name))))
 
+; propertize definition for XEmacs, stolen from erc-compat
+(eval-when-compile
+  (unless (fboundp 'propertize)
+    (defun propertize (string &rest props)
+      (let ((string (copy-sequence string)))
+        (while props
+          (put-text-property 0 (length string) (nth 0 props) (nth 1 props) string)
+          (setq props (cddr props)))
+        string))))
 
 ;;;; Wrappers for basic git commands
 ;;;; ------------------------------------------------------------
@@ -448,11 +457,10 @@ and returns the process output as a string."
 
 (defun git-fileinfo-prettyprint (info)
   "Pretty-printer for the git-fileinfo structure."
-  (insert (format "   %s %s %s  %s%s"
-                  (if (git-fileinfo->marked info) (propertize "*" 'face 'git-mark-face) " ")
-                  (git-status-code-as-string (git-fileinfo->state info))
-                  (git-permissions-as-string (git-fileinfo->old-perm info) (git-fileinfo->new-perm info))
-                  (git-escape-file-name (git-fileinfo->name info))
+  (insert (concat "   " (if (git-fileinfo->marked info) (propertize "*" 'face 'git-mark-face) " ")
+                  " " (git-status-code-as-string (git-fileinfo->state info))
+                  " " (git-permissions-as-string (git-fileinfo->old-perm info) (git-fileinfo->new-perm info))
+                  "  " (git-escape-file-name (git-fileinfo->name info))
                   (git-rename-as-string info))))
 
 (defun git-parse-status (status)
diff --git a/describe.c b/describe.c
deleted file mode 100644 (file)
index f4029ee..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-#include "cache.h"
-#include "commit.h"
-#include "tag.h"
-#include "refs.h"
-
-#define SEEN (1u << 0)
-
-static const char describe_usage[] =
-"git-describe [--all] [--tags] [--abbrev=<n>] <committish>*";
-
-static int all;        /* Default to annotated tags only */
-static int tags;       /* But allow any tags if --tags is specified */
-
-static int abbrev = DEFAULT_ABBREV;
-
-static int names, allocs;
-static struct commit_name {
-       const struct commit *commit;
-       int prio; /* annotated tag = 2, tag = 1, head = 0 */
-       char path[FLEX_ARRAY]; /* more */
-} **name_array = NULL;
-
-static struct commit_name *match(struct commit *cmit)
-{
-       int i = names;
-       struct commit_name **p = name_array;
-
-       while (i-- > 0) {
-               struct commit_name *n = *p++;
-               if (n->commit == cmit)
-                       return n;
-       }
-       return NULL;
-}
-
-static void add_to_known_names(const char *path,
-                              const struct commit *commit,
-                              int prio)
-{
-       int idx;
-       int len = strlen(path)+1;
-       struct commit_name *name = xmalloc(sizeof(struct commit_name) + len);
-
-       name->commit = commit;
-       name->prio = prio;
-       memcpy(name->path, path, len);
-       idx = names;
-       if (idx >= allocs) {
-               allocs = (idx + 50) * 3 / 2;
-               name_array = xrealloc(name_array, allocs*sizeof(*name_array));
-       }
-       name_array[idx] = name;
-       names = ++idx;
-}
-
-static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
-{
-       struct commit *commit = lookup_commit_reference_gently(sha1, 1);
-       struct object *object;
-       int prio;
-
-       if (!commit)
-               return 0;
-       object = parse_object(sha1);
-       /* If --all, then any refs are used.
-        * If --tags, then any tags are used.
-        * Otherwise only annotated tags are used.
-        */
-       if (!strncmp(path, "refs/tags/", 10)) {
-               if (object->type == OBJ_TAG)
-                       prio = 2;
-               else
-                       prio = 1;
-       }
-       else
-               prio = 0;
-
-       if (!all) {
-               if (!prio)
-                       return 0;
-               if (!tags && prio < 2)
-                       return 0;
-       }
-       add_to_known_names(all ? path + 5 : path + 10, commit, prio);
-       return 0;
-}
-
-static int compare_names(const void *_a, const void *_b)
-{
-       struct commit_name *a = *(struct commit_name **)_a;
-       struct commit_name *b = *(struct commit_name **)_b;
-       unsigned long a_date = a->commit->date;
-       unsigned long b_date = b->commit->date;
-
-       if (a->prio != b->prio)
-               return b->prio - a->prio;
-       return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
-}
-
-static void describe(const char *arg, int last_one)
-{
-       unsigned char sha1[20];
-       struct commit *cmit;
-       struct commit_list *list;
-       static int initialized = 0;
-       struct commit_name *n;
-
-       if (get_sha1(arg, sha1))
-               die("Not a valid object name %s", arg);
-       cmit = lookup_commit_reference(sha1);
-       if (!cmit)
-               die("%s is not a valid '%s' object", arg, commit_type);
-
-       if (!initialized) {
-               initialized = 1;
-               for_each_ref(get_name, NULL);
-               qsort(name_array, names, sizeof(*name_array), compare_names);
-       }
-
-       n = match(cmit);
-       if (n) {
-               printf("%s\n", n->path);
-               return;
-       }
-
-       list = NULL;
-       commit_list_insert(cmit, &list);
-       while (list) {
-               struct commit *c = pop_most_recent_commit(&list, SEEN);
-               n = match(c);
-               if (n) {
-                       printf("%s-g%s\n", n->path,
-                              find_unique_abbrev(cmit->object.sha1, abbrev));
-                       if (!last_one)
-                               clear_commit_marks(cmit, SEEN);
-                       return;
-               }
-       }
-       die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1));
-}
-
-int main(int argc, char **argv)
-{
-       int i;
-
-       for (i = 1; i < argc; i++) {
-               const char *arg = argv[i];
-
-               if (*arg != '-')
-                       break;
-               else if (!strcmp(arg, "--all"))
-                       all = 1;
-               else if (!strcmp(arg, "--tags"))
-                       tags = 1;
-               else if (!strncmp(arg, "--abbrev=", 9)) {
-                       abbrev = strtoul(arg + 9, NULL, 10);
-                       if (abbrev < MINIMUM_ABBREV || 40 < abbrev)
-                               abbrev = DEFAULT_ABBREV;
-               }
-               else
-                       usage(describe_usage);
-       }
-
-       setup_git_directory();
-
-       if (argc <= i)
-               describe("HEAD", 1);
-       else
-               while (i < argc) {
-                       describe(argv[i], (i == argc - 1));
-                       i++;
-               }
-
-       return 0;
-}
index d9eb79d1aa8dccf18fa0df89abdc5d3fdfd2aa24..59d663ba9e0c3828d11b442c6fd9536a87d937cb 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -128,7 +128,7 @@ do
        -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
        sign=t; shift ;;
        -u|--u|--ut|--utf|--utf8)
-       shift ;; # this is now default
+       utf8=t; shift ;; # this is now default
        --no-u|--no-ut|--no-utf|--no-utf8)
        utf8=; shift ;;
        -k|--k|--ke|--kee|--keep)
@@ -228,6 +228,8 @@ fi
 if test "$(cat "$dotest/utf8")" = t
 then
        utf8=-u
+else
+       utf8=-n
 fi
 if test "$(cat "$dotest/keep")" = t
 then
index 5569fdcc3463b214411d5a168a00783b0d390044..1f68599ae51a671f8c7a3a01c6aa9c6b205dd217 100755 (executable)
@@ -23,11 +23,12 @@ USAGE='[-u] [-k] [-q] [-m] (-c .dotest/<num> | mbox) [signoff]'
 
 git var GIT_COMMITTER_IDENT >/dev/null || exit
 
-keep_subject= query_apply= continue= utf8= resume=t
+keep_subject= query_apply= continue= utf8=-u resume=t
 while case "$#" in 0) break ;; esac
 do
        case "$1" in
        -u)     utf8=-u ;;
+       -n)     utf8=-n ;;
        -k)     keep_subject=-k ;;
        -q)     query_apply=t ;;
        -c)     continue="$2"; resume=f; shift ;;
index 3d388de62a9ee212c8f54f3a5dc9a8b823bc8934..cf761b2c694d9e6cbcfc8cd1e075095d34ba857b 100755 (executable)
@@ -355,7 +355,7 @@ then
        # The name under $remote_top the remote HEAD seems to point at.
        head_points_at=$(
                (
-                       echo "master"
+                       test -f "$GIT_DIR/$remote_top/master" && echo "master"
                        cd "$GIT_DIR/$remote_top" &&
                        find . -type f -print | sed -e 's/^\.\///'
                ) | (
index e023bf141363d87abfef358134e484ea85f32a15..f8d46d587bec2b4dbab0263fa3df97e60beb08e4 100644 (file)
@@ -107,6 +107,11 @@ extern int git_munmap(void *start, size_t length);
 #define DEFAULT_PACKED_GIT_LIMIT \
        ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
 
+#ifdef NO_PREAD
+#define pread git_pread
+extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
+#endif
+
 #ifdef NO_SETENV
 #define setenv gitsetenv
 extern int gitsetenv(const char *, const char *, int);
index ba39d393843733b46f309deb105c90cabcee2cb1..8dc2ee0cf7461ace62c5ef7afac6dedc7814ddfb 100755 (executable)
@@ -402,6 +402,15 @@ sub make_message_id
 $cc = "";
 $time = time - scalar $#files;
 
+sub unquote_rfc2047 {
+       local ($_) = @_;
+       if (s/=\?utf-8\?q\?(.*)\?=/$1/g) {
+               s/_/ /g;
+               s/=([0-9A-F]{2})/chr(hex($1))/eg;
+       }
+       return "$_ - unquoted";
+}
+
 sub send_message
 {
        my @recipients = unique_email_list(@to);
@@ -555,6 +564,7 @@ sub send_message
        }
        close F;
        if (defined $author_not_sender) {
+               $author_not_sender = unquote_rfc2047($author_not_sender);
                $message = "From: $author_not_sender\n\n$message";
        }
 
diff --git a/git.c b/git.c
index bf55499dc3d555dfaa853b0c6e4aec5439c3532e..9ce545d67693c8713b4254d5fa0e186723e348c2 100644 (file)
--- a/git.c
+++ b/git.c
@@ -220,6 +220,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                { "cherry", cmd_cherry, RUN_SETUP },
                { "commit-tree", cmd_commit_tree, RUN_SETUP },
                { "count-objects", cmd_count_objects, RUN_SETUP },
+               { "describe", cmd_describe, RUN_SETUP },
                { "diff", cmd_diff, RUN_SETUP | USE_PAGER },
                { "diff-files", cmd_diff_files, RUN_SETUP },
                { "diff-index", cmd_diff_index, RUN_SETUP },
index 25e5079a89dd22e7c8eb2b7e3ac276681eae83b4..88af2e638061f54cfd7f6ffc6ae777ef2756c603 100755 (executable)
@@ -2412,7 +2412,6 @@ sub git_patchset_body {
 
                        push @diff_header, $patch_line;
                }
-               #last PATCH unless $patch_line;
                my $last_patch_line = $patch_line;
 
                # check if current patch belong to current raw line
@@ -2522,7 +2521,10 @@ sub git_patchset_body {
 
                # from-file/to-file diff header
                $patch_line = $last_patch_line;
-               last PATCH unless $patch_line;
+               if (! $patch_line) {
+                       print "</div>\n"; # class="patch"
+                       last PATCH;
+               }
                next PATCH if ($patch_line =~ m/^diff /);
                #assert($patch_line =~ m/^---/) if DEBUG;
                if ($from{'href'} && $patch_line =~ m!^--- "?a/!) {
@@ -2533,7 +2535,6 @@ sub git_patchset_body {
                print "<div class=\"diff from_file\">$patch_line</div>\n";
 
                $patch_line = <$fd>;
-               #last PATCH unless $patch_line;
                chomp $patch_line;
 
                #assert($patch_line =~ m/^+++/) if DEBUG;
index fe8cd7bdcd18748d9dac839e3298a16f85d91007..67dfb0a0337b63bd4c1ef5b9d3228735bf66f1b3 100644 (file)
@@ -809,6 +809,7 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
                return error("Unable to start request");
        }
 
+       target->pack_size = ftell(packfile);
        fclose(packfile);
 
        ret = move_temp_to_file(tmpfile, filename);
index 7e73eac9c3476053c337a361106397c35ae3ee79..0a15f5378288992826e7042a3b9dff92fef4c080 100644 (file)
@@ -770,11 +770,14 @@ static void finish_request(struct transfer_request *request)
                                request->url, curl_errorstr);
                        remote->can_update_info_refs = 0;
                } else {
+                       off_t pack_size = ftell(request->local_stream);
+
                        fclose(request->local_stream);
                        request->local_stream = NULL;
                        if (!move_temp_to_file(request->tmpfile,
                                               request->filename)) {
                                target = (struct packed_git *)request->userData;
+                               target->pack_size = pack_size;
                                lst = &remote->packs;
                                while (*lst != target)
                                        lst = &((*lst)->next);
index 095a7e1622326e9e456d138b35c73b4a2777c8e5..53e25f278c6193860431f63a3c9de97f4e347f27 100644 (file)
 #endif
 #endif
 
+#ifdef NO_C99_FORMAT
+#define SZ_FMT "lu"
+#else
+#define SZ_FMT "zu"
+#endif
+
 const unsigned char null_sha1[20];
 
 static unsigned int sha1_file_open_flag = O_NOATIME;
@@ -407,9 +413,9 @@ struct packed_git *packed_git;
 void pack_report()
 {
        fprintf(stderr,
-               "pack_report: getpagesize()            = %10lu\n"
-               "pack_report: core.packedGitWindowSize = %10lu\n"
-               "pack_report: core.packedGitLimit      = %10lu\n",
+               "pack_report: getpagesize()            = %10" SZ_FMT "\n"
+               "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
+               "pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
                page_size,
                packed_git_window_size,
                packed_git_limit);
@@ -417,7 +423,8 @@ void pack_report()
                "pack_report: pack_used_ctr            = %10u\n"
                "pack_report: pack_mmap_calls          = %10u\n"
                "pack_report: pack_open_windows        = %10u / %10u\n"
-               "pack_report: pack_mapped              = %10lu / %10lu\n",
+               "pack_report: pack_mapped              = "
+                       "%10" SZ_FMT " / %10" SZ_FMT "\n",
                pack_used_ctr,
                pack_mmap_calls,
                pack_open_windows, peak_pack_open_windows,
index 738d1513d49356d4e7a8eaec4b5df61a0e07881c..8e8d526ef2e68fb8f50b9164f2ff032bafa104d6 100755 (executable)
@@ -71,6 +71,8 @@ test_expect_success setup '
        check_fsck &&
 
        chmod +x C &&
+       ( test "`git repo-config --bool core.filemode`" != false ||
+         echo executable >>C ) &&
        git add C &&
        test_tick && git commit -m dragon &&
        L=`git rev-parse --verify HEAD` &&
index 22f4550b6ca4d2cb185fc19f6be414a8a0874a60..70f899957e8ce511f0f5a470e8b6927d58d1b63e 100644 (file)
@@ -199,10 +199,17 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
        int retval;
        void *tree;
        struct tree_desc t;
+       unsigned char root[20];
 
-       tree = read_object_with_reference(tree_sha1, tree_type, &t.size, NULL);
+       tree = read_object_with_reference(tree_sha1, tree_type, &t.size, root);
        if (!tree)
                return -1;
+
+       if (name[0] == '\0') {
+               hashcpy(sha1, root);
+               return 0;
+       }
+
        t.buf = tree;
        retval = find_tree_entry(&t, name, sha1, mode);
        free(tree);