Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Fri, 24 Jul 2009 16:27:09 +0000 (09:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 24 Jul 2009 16:27:09 +0000 (09:27 -0700)
* maint:
SunOS grep does not understand -C<n> nor -e
Fix export_marks() error handling.
git branch: clean up detached branch handling
git branch: avoid unnecessary object lookups
git branch: fix performance problem
do_one_ref(): null_sha1 check is not about broken ref

Conflicts:
Makefile

1  2 
Makefile
builtin-branch.c
builtin-fast-export.c
refs.c
diff --combined Makefile
index bde27ed478c29a9e5866219eec09a76c828b7ce7,f88ed3e14d2421fdd730705d2aac0c317d6f94e0..daf4296706c4c9c524b6ec4434cadcf95881ea25
+++ b/Makefile
@@@ -3,11 -3,6 +3,11 @@@ all:
  
  # Define V=1 to have a more verbose compile.
  #
 +# Define SHELL_PATH to a POSIX shell if your /bin/sh is broken.
 +#
 +# Define SANE_TOOL_PATH to a colon-separated list of paths to prepend
 +# to PATH if your tools in /usr/bin are broken.
 +#
  # Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
  # or vsnprintf() return -1 instead of number of characters which would
  # have been written to the final string if enough space had been available.
  #
  # Define NO_MKDTEMP if you don't have mkdtemp in the C library.
  #
 +# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
 +#
 +# Define NO_LIBGEN_H if you don't have libgen.h.
 +#
 +# Define NEEDS_LIBGEN if your libgen needs -lgen when linking
 +#
  # Define NO_SYS_SELECT_H if you don't have sys/select.h.
  #
  # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
  # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
  # Patrick Mauritz).
  #
 +# Define NEEDS_RESOLV if linking with -lnsl and/or -lsocket is not enough.
 +# Notably on Solaris hstrerror resides in libresolv and on Solaris 7
 +# inet_ntop and inet_pton additionally reside there.
 +#
  # Define NO_MMAP if you want to avoid mmap.
  #
  # Define NO_PTHREADS if you do not have or do not want to use Pthreads.
  #
  # Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed
  # programs as a tar, where bin/ and libexec/ might be on different file systems.
 +#
 +# Define USE_NED_ALLOCATOR if you want to replace the platforms default
 +# memory allocators with the nedmalloc allocator written by Niall Douglas.
 +#
 +# Define NO_REGEX if you have no or inferior regex support in your C library.
  
  GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
        @$(SHELL_PATH) ./GIT-VERSION-GEN
@@@ -248,7 -228,6 +248,7 @@@ ETC_GITCONFIG = etc/gitconfi
  endif
  lib = lib
  # DESTDIR=
 +pathsep = :
  
  # default configuration for gitweb
  GITWEB_CONFIG = gitweb_config.perl
@@@ -356,6 -335,7 +356,6 @@@ PROGRAMS += git-index-pack$
  PROGRAMS += git-merge-index$X
  PROGRAMS += git-merge-tree$X
  PROGRAMS += git-mktag$X
 -PROGRAMS += git-mktree$X
  PROGRAMS += git-pack-redundant$X
  PROGRAMS += git-patch-id$X
  PROGRAMS += git-shell$X
@@@ -609,7 -589,6 +609,7 @@@ BUILTIN_OBJS += builtin-merge-base.
  BUILTIN_OBJS += builtin-merge-file.o
  BUILTIN_OBJS += builtin-merge-ours.o
  BUILTIN_OBJS += builtin-merge-recursive.o
 +BUILTIN_OBJS += builtin-mktree.o
  BUILTIN_OBJS += builtin-mv.o
  BUILTIN_OBJS += builtin-name-rev.o
  BUILTIN_OBJS += builtin-pack-objects.o
@@@ -656,12 -635,10 +656,12 @@@ EXTLIBS 
  
  ifeq ($(uname_S),Linux)
        NO_STRLCPY = YesPlease
 +      NO_MKSTEMPS = YesPlease
        THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),GNU/kFreeBSD)
        NO_STRLCPY = YesPlease
 +      NO_MKSTEMPS = YesPlease
        THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),UnixWare)
        SHELL_PATH = /usr/local/bin/bash
        NO_IPV6 = YesPlease
        NO_HSTRERROR = YesPlease
 +      NO_MKSTEMPS = YesPlease
        BASIC_CFLAGS += -Kthread
        BASIC_CFLAGS += -I/usr/local/include
        BASIC_LDFLAGS += -L/usr/local/lib
@@@ -697,7 -673,6 +697,7 @@@ ifeq ($(uname_S),SCO_SV
        SHELL_PATH = /usr/bin/bash
        NO_IPV6 = YesPlease
        NO_HSTRERROR = YesPlease
 +      NO_MKSTEMPS = YesPlease
        BASIC_CFLAGS += -I/usr/local/include
        BASIC_LDFLAGS += -L/usr/local/lib
        NO_STRCASESTR = YesPlease
@@@ -722,22 -697,12 +722,23 @@@ ifeq ($(uname_S),SunOS
        NEEDS_SOCKET = YesPlease
        NEEDS_NSL = YesPlease
        SHELL_PATH = /bin/bash
 +      SANE_TOOL_PATH = /usr/xpg6/bin:/usr/xpg4/bin
        NO_STRCASESTR = YesPlease
        NO_MEMMEM = YesPlease
 -      NO_HSTRERROR = YesPlease
        NO_MKDTEMP = YesPlease
 -      OLD_ICONV = UnfortunatelyYes
 +      NO_MKSTEMPS = YesPlease
 +      NO_REGEX = YesPlease
+       NO_EXTERNAL_GREP = YesPlease
 +      ifeq ($(uname_R),5.7)
 +              NEEDS_RESOLV = YesPlease
 +              NO_IPV6 = YesPlease
 +              NO_SOCKADDR_STORAGE = YesPlease
 +              NO_UNSETENV = YesPlease
 +              NO_SETENV = YesPlease
 +              NO_STRLCPY = YesPlease
 +              NO_C99_FORMAT = YesPlease
 +              NO_STRTOUMAX = YesPlease
 +      endif
        ifeq ($(uname_R),5.8)
                NO_UNSETENV = YesPlease
                NO_SETENV = YesPlease
                NO_C99_FORMAT = YesPlease
                NO_STRTOUMAX = YesPlease
        endif
 -      INSTALL = ginstall
 +      ifdef NO_IPV6
 +              NEEDS_RESOLV = YesPlease
 +      endif
 +      INSTALL = /usr/ucb/install
        TAR = gtar
 -      BASIC_CFLAGS += -D__EXTENSIONS__
 +      BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H
  endif
  ifeq ($(uname_O),Cygwin)
        NO_D_TYPE_IN_DIRENT = YesPlease
        NO_D_INO_IN_DIRENT = YesPlease
        NO_STRCASESTR = YesPlease
        NO_MEMMEM = YesPlease
 +      NO_MKSTEMPS = YesPlease
        NO_SYMLINK_HEAD = YesPlease
        NEEDS_LIBICONV = YesPlease
        NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
@@@ -806,13 -767,11 +807,13 @@@ ifeq ($(uname_S),NetBSD
        BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib
        THREADED_DELTA_SEARCH = YesPlease
        USE_ST_TIMESPEC = YesPlease
 +      NO_MKSTEMPS = YesPlease
  endif
  ifeq ($(uname_S),AIX)
        NO_STRCASESTR=YesPlease
        NO_MEMMEM = YesPlease
        NO_MKDTEMP = YesPlease
 +      NO_MKSTEMPS = YesPlease
        NO_STRLCPY = YesPlease
        NO_NSEC = YesPlease
        FREAD_READS_DIRECTORIES = UnfortunatelyYes
@@@ -828,40 -787,24 +829,40 @@@ endi
  ifeq ($(uname_S),GNU)
        # GNU/Hurd
        NO_STRLCPY=YesPlease
 +      NO_MKSTEMPS = YesPlease
 +endif
 +ifeq ($(uname_S),IRIX)
 +      NO_SETENV = YesPlease
 +      NO_UNSETENV = YesPlease
 +      NO_STRCASESTR = YesPlease
 +      NO_MEMMEM = YesPlease
 +      NO_MKSTEMPS = YesPlease
 +      NO_MKDTEMP = YesPlease
 +      NO_MMAP = YesPlease
 +      NO_EXTERNAL_GREP = UnfortunatelyYes
 +      SNPRINTF_RETURNS_BOGUS = YesPlease
 +      SHELL_PATH = /usr/gnu/bin/bash
 +      NEEDS_LIBGEN = YesPlease
  endif
  ifeq ($(uname_S),IRIX64)
 -      NO_IPV6=YesPlease
        NO_SETENV=YesPlease
 +      NO_UNSETENV = YesPlease
        NO_STRCASESTR=YesPlease
        NO_MEMMEM = YesPlease
 -      NO_STRLCPY = YesPlease
 -      NO_SOCKADDR_STORAGE=YesPlease
 +      NO_MKSTEMPS = YesPlease
 +      NO_MKDTEMP = YesPlease
 +      NO_MMAP = YesPlease
 +      NO_EXTERNAL_GREP = UnfortunatelyYes
 +      SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH=/usr/gnu/bin/bash
 -      BASIC_CFLAGS += -DPATH_MAX=1024
 -      # for now, build 32-bit version
 -      BASIC_LDFLAGS += -L/usr/lib32
 +      NEEDS_LIBGEN = YesPlease
  endif
  ifeq ($(uname_S),HP-UX)
        NO_IPV6=YesPlease
        NO_SETENV=YesPlease
        NO_STRCASESTR=YesPlease
        NO_MEMMEM = YesPlease
 +      NO_MKSTEMPS = YesPlease
        NO_STRLCPY = YesPlease
        NO_MKDTEMP = YesPlease
        NO_UNSETENV = YesPlease
@@@ -874,10 -817,9 +875,10 @@@ ifneq (,$(findstring CYGWIN,$(uname_S))
        UNRELIABLE_FSTAT = UnfortunatelyYes
  endif
  ifneq (,$(findstring MINGW,$(uname_S)))
 +      pathsep = ;
        NO_PREAD = YesPlease
        NO_OPENSSL = YesPlease
 -      NO_CURL = YesPlease
 +      NO_LIBGEN_H = YesPlease
        NO_SYMLINK_HEAD = YesPlease
        NO_IPV6 = YesPlease
        NO_SETENV = YesPlease
        NO_STRCASESTR = YesPlease
        NO_STRLCPY = YesPlease
        NO_MEMMEM = YesPlease
 -      NO_PTHREADS = YesPlease
        NEEDS_LIBICONV = YesPlease
        OLD_ICONV = YesPlease
        NO_C99_FORMAT = YesPlease
        NO_STRTOUMAX = YesPlease
        NO_MKDTEMP = YesPlease
 +      NO_MKSTEMPS = YesPlease
        SNPRINTF_RETURNS_BOGUS = YesPlease
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
 +      USE_NED_ALLOCATOR = YesPlease
        UNRELIABLE_FSTAT = UnfortunatelyYes
        OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
 -      COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
 -      COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
 +      NO_REGEX = YesPlease
 +      COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
        COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
 -      COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o
 +      COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
        EXTLIBS += -lws2_32
        X = .exe
 +ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
 +      htmldir=doc/git/html/
 +      prefix =
 +      INSTALL = /bin/install
 +      EXTLIBS += /mingw/lib/libz.a
 +      NO_R_TO_GCC_LINKER = YesPlease
 +      INTERNAL_QSORT = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
 +else
 +      NO_CURL = YesPlease
 +      NO_PTHREADS = YesPlease
 +endif
  endif
  ifneq (,$(findstring arm,$(uname_M)))
        ARM_SHA1 = YesPlease
 +      NO_MKSTEMPS = YesPlease
  endif
  
  -include config.mak.autogen
  -include config.mak
  
 +ifdef SANE_TOOL_PATH
 +SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH))
 +BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix $(SANE_TOOL_PATH_SQ)|'
 +PATH := $(SANE_TOOL_PATH):${PATH}
 +else
 +BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d'
 +endif
 +
  ifeq ($(uname_S),Darwin)
        ifndef NO_FINK
                ifeq ($(shell test -d /sw/lib && echo y),y)
@@@ -963,11 -883,6 +964,11 @@@ ifndef CC_LD_DYNPAT
        endif
  endif
  
 +ifdef NO_LIBGEN_H
 +      COMPAT_CFLAGS += -DNO_LIBGEN_H
 +      COMPAT_OBJS += compat/basename.o
 +endif
 +
  ifdef NO_CURL
        BASIC_CFLAGS += -DNO_CURL
  else
@@@ -1034,18 -949,12 +1035,18 @@@ ifdef NEEDS_LIBICON
        endif
        EXTLIBS += $(ICONV_LINK) -liconv
  endif
 +ifdef NEEDS_LIBGEN
 +      EXTLIBS += -lgen
 +endif
  ifdef NEEDS_SOCKET
        EXTLIBS += -lsocket
  endif
  ifdef NEEDS_NSL
        EXTLIBS += -lnsl
  endif
 +ifdef NEEDS_RESOLV
 +      EXTLIBS += -lresolv
 +endif
  ifdef NO_D_TYPE_IN_DIRENT
        BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT
  endif
@@@ -1101,10 -1010,6 +1102,10 @@@ ifdef NO_MKDTEM
        COMPAT_CFLAGS += -DNO_MKDTEMP
        COMPAT_OBJS += compat/mkdtemp.o
  endif
 +ifdef NO_MKSTEMPS
 +      COMPAT_CFLAGS += -DNO_MKSTEMPS
 +      COMPAT_OBJS += compat/mkstemps.o
 +endif
  ifdef NO_UNSETENV
        COMPAT_CFLAGS += -DNO_UNSETENV
        COMPAT_OBJS += compat/unsetenv.o
@@@ -1222,15 -1127,6 +1223,15 @@@ endi
  ifdef UNRELIABLE_FSTAT
        BASIC_CFLAGS += -DUNRELIABLE_FSTAT
  endif
 +ifdef NO_REGEX
 +      COMPAT_CFLAGS += -Icompat/regex
 +      COMPAT_OBJS += compat/regex/regex.o
 +endif
 +
 +ifdef USE_NED_ALLOCATOR
 +       COMPAT_CFLAGS += -DUSE_NED_ALLOCATOR -DOVERRIDE_STRDUP -DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR -Icompat/nedmalloc
 +       COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
 +endif
  
  ifeq ($(TCLTK_PATH),)
  NO_TCLTK=NoThanks
@@@ -1306,7 -1202,7 +1307,7 @@@ SHELL = $(SHELL_PATH
  
  all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
  ifneq (,$X)
 -      $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
 +      $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
  endif
  
  all::
@@@ -1357,9 -1253,9 +1358,9 @@@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %
        $(QUIET_GEN)$(RM) $@ $@+ && \
        sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
            -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
 -          -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
            -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
            -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
 +          -e $(BROKEN_PATH_FIX) \
            $@.sh >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
@@@ -1376,7 -1272,7 +1377,7 @@@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % 
        sed -e '1{' \
            -e '        s|#!.*perl|#!$(PERL_PATH_SQ)|' \
            -e '        h' \
 -          -e '        s=.*=use lib (split(/:/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \
 +          -e '        s=.*=use lib (split(/$(pathsep)/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \
            -e '        H' \
            -e '        x' \
            -e '}' \
@@@ -1599,8 -1495,6 +1600,8 @@@ test-delta$X: diff-delta.o patch-delta.
  
  test-parse-options$X: parse-options.o
  
 +test-parse-options.o: parse-options.h
 +
  .PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
  
  test-%$X: test-%.o $(GITLIBS)
@@@ -1659,16 -1553,15 +1660,16 @@@ ifneq (,$X
  endif
        bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
        execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
 -      { $(RM) "$$execdir/git-add$X" && \
 +      { test "$$bindir/" = "$$execdir/" || \
 +              { $(RM) "$$execdir/git$X" && \
                test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
 -              ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \
 -              cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \
 -      { for p in $(filter-out git-add$X,$(BUILT_INS)); do \
 +              ln "$$bindir/git$X" "$$execdir/git$X" 2>/dev/null || \
 +              cp "$$bindir/git$X" "$$execdir/git$X"; } ; } && \
 +      { for p in $(BUILT_INS); do \
                $(RM) "$$execdir/$$p" && \
 -              ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \
 -              ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \
 -              cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \
 +              ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
 +              ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
 +              cp "$$execdir/git$X" "$$execdir/$$p" || exit; \
          done; } && \
        ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
  
@@@ -1749,7 -1642,7 +1750,7 @@@ distclean: clea
        $(RM) configure
  
  clean:
 -      $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
 +      $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
                $(LIB_FILE) $(XDIFF_LIB)
        $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
        $(RM) $(TEST_PROGRAMS)
diff --combined builtin-branch.c
index 5687d6042ced29e60aa1999dc9d73eb6c38b8e77,887fa60fa54139eb5e25f801e5b964978db846ab..1a03d5f356009de12364c320577e24853bec7959
@@@ -191,7 -191,7 +191,7 @@@ struct ref_item 
  
  struct ref_list {
        struct rev_info revs;
-       int index, alloc, maxwidth;
+       int index, alloc, maxwidth, verbose, abbrev;
        struct ref_item *list;
        struct commit_list *with_commit;
        int kinds;
@@@ -240,21 -240,24 +240,24 @@@ static int append_ref(const char *refna
        if (ARRAY_SIZE(ref_kind) <= i)
                return 0;
  
-       commit = lookup_commit_reference_gently(sha1, 1);
-       if (!commit)
-               return error("branch '%s' does not point at a commit", refname);
-       /* Filter with with_commit if specified */
-       if (!is_descendant_of(commit, ref_list->with_commit))
-               return 0;
        /* Don't add types the caller doesn't want */
        if ((kind & ref_list->kinds) == 0)
                return 0;
  
-       if (merge_filter != NO_FILTER)
-               add_pending_object(&ref_list->revs,
-                                  (struct object *)commit, refname);
+       commit = NULL;
+       if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
+               commit = lookup_commit_reference_gently(sha1, 1);
+               if (!commit)
+                       return error("branch '%s' does not point at a commit", refname);
+               /* Filter with with_commit if specified */
+               if (!is_descendant_of(commit, ref_list->with_commit))
+                       return 0;
+               if (merge_filter != NO_FILTER)
+                       add_pending_object(&ref_list->revs,
+                                          (struct object *)commit, refname);
+       }
  
        /* Resize buffer */
        if (ref_list->index >= ref_list->alloc) {
@@@ -415,18 -418,38 +418,38 @@@ static int calc_maxwidth(struct ref_lis
        return w;
  }
  
+ static void show_detached(struct ref_list *ref_list)
+ {
+       struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
+       if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
+               struct ref_item item;
+               item.name = xstrdup("(no branch)");
+               item.len = strlen(item.name);
+               item.kind = REF_LOCAL_BRANCH;
+               item.dest = NULL;
+               item.commit = head_commit;
+               if (item.len > ref_list->maxwidth)
+                       ref_list->maxwidth = item.len;
+               print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
+               free(item.name);
+       }
+ }
  static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)
  {
        int i;
        struct ref_list ref_list;
-       struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
  
        memset(&ref_list, 0, sizeof(ref_list));
        ref_list.kinds = kinds;
+       ref_list.verbose = verbose;
+       ref_list.abbrev = abbrev;
        ref_list.with_commit = with_commit;
        if (merge_filter != NO_FILTER)
                init_revisions(&ref_list.revs, NULL);
-       for_each_ref(append_ref, &ref_list);
+       for_each_rawref(append_ref, &ref_list);
        if (merge_filter != NO_FILTER) {
                struct commit *filter;
                filter = lookup_commit_reference_gently(merge_filter_ref, 0);
        qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
  
        detached = (detached && (kinds & REF_LOCAL_BRANCH));
-       if (detached && head_commit &&
-           is_descendant_of(head_commit, with_commit)) {
-               struct ref_item item;
-               item.name = xstrdup("(no branch)");
-               item.len = strlen(item.name);
-               item.kind = REF_LOCAL_BRANCH;
-               item.dest = NULL;
-               item.commit = head_commit;
-               if (item.len > ref_list.maxwidth)
-                       ref_list.maxwidth = item.len;
-               print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1, "");
-               free(item.name);
-       }
+       if (detached)
+               show_detached(&ref_list);
  
        for (i = 0; i < ref_list.index; i++) {
                int current = !detached &&
@@@ -547,7 -559,7 +559,7 @@@ int cmd_branch(int argc, const char **a
        struct option options[] = {
                OPT_GROUP("Generic options"),
                OPT__VERBOSE(&verbose),
 -              OPT_SET_INT( 0 , "track",  &track, "set up tracking mode (see git-pull(1))",
 +              OPT_SET_INT('t', "track",  &track, "set up tracking mode (see git-pull(1))",
                        BRANCH_TRACK_EXPLICIT),
                OPT_BOOLEAN( 0 , "color",  &branch_use_color, "use colored output"),
                OPT_SET_INT('r', NULL,     &kinds, "act on remote-tracking branches",
        }
        hashcpy(merge_filter_ref, head_sha1);
  
 -      argc = parse_options(argc, argv, options, builtin_branch_usage, 0);
 +      argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 +                           0);
        if (!!delete + !!rename + !!force_create > 1)
                usage_with_options(builtin_branch_usage, options);
  
diff --combined builtin-fast-export.c
index 9a8a6fc6b1e98162a1548b40bd4281172e18d7b2,9091481fd537c7bc855183232a75dfa6e386b8c3..ca198250c3082be82cdca09954198d6617b95bf8
@@@ -119,7 -119,7 +119,7 @@@ static void handle_object(const unsigne
  
        printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
        if (size && fwrite(buf, size, 1, stdout) != 1)
 -              die ("Could not write blob %s", sha1_to_hex(sha1));
 +              die_errno ("Could not write blob '%s'", sha1_to_hex(sha1));
        printf("\n");
  
        show_progress();
@@@ -428,21 -428,27 +428,27 @@@ static void export_marks(char *file
        uint32_t mark;
        struct object_decoration *deco = idnums.hash;
        FILE *f;
+       int e = 0;
  
        f = fopen(file, "w");
        if (!f)
-               error("Unable to open marks file %s for writing", file);
+               error("Unable to open marks file %s for writing.", file);
  
        for (i = 0; i < idnums.size; i++) {
                if (deco->base && deco->base->type == 1) {
                        mark = ptr_to_mark(deco->decoration);
-                       fprintf(f, ":%"PRIu32" %s\n", mark,
-                               sha1_to_hex(deco->base->sha1));
+                       if (fprintf(f, ":%"PRIu32" %s\n", mark,
+                               sha1_to_hex(deco->base->sha1)) < 0) {
+                           e = 1;
+                           break;
+                       }
                }
                deco++;
        }
  
-       if (ferror(f) || fclose(f))
+       e |= ferror(f);
+       e |= fclose(f);
+       if (e)
                error("Unable to write marks file %s.", file);
  }
  
@@@ -451,7 -457,7 +457,7 @@@ static void import_marks(char *input_fi
        char line[512];
        FILE *f = fopen(input_file, "r");
        if (!f)
 -              die("cannot read %s: %s", input_file, strerror(errno));
 +              die_errno("cannot read '%s'", input_file);
  
        while (fgets(line, sizeof(line), f)) {
                uint32_t mark;
@@@ -515,7 -521,7 +521,7 @@@ int cmd_fast_export(int argc, const cha
  
        init_revisions(&revs, prefix);
        argc = setup_revisions(argc, argv, &revs, NULL);
 -      argc = parse_options(argc, argv, options, fast_export_usage, 0);
 +      argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0);
        if (argc > 1)
                usage_with_options (fast_export_usage, options);
  
diff --combined refs.c
index e15880fbc836c8111799da3a4b6f32afe2604db9,3da3c8cefcbe123485fb5a68f2406488275ce43b..e49eaa3089c39028e3c0af90422672db63fff198
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -531,9 -531,10 +531,10 @@@ static int do_one_ref(const char *base
  {
        if (strncmp(base, entry->name, trim))
                return 0;
+       /* Is this a "negative ref" that represents a deleted ref? */
+       if (is_null_sha1(entry->sha1))
+               return 0;
        if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
-               if (is_null_sha1(entry->sha1))
-                       return 0;
                if (!has_sha1_file(entry->sha1)) {
                        error("%s does not point to a valid object!", entry->name);
                        return 0;
@@@ -682,13 -683,12 +683,13 @@@ int for_each_rawref(each_ref_fn fn, voi
   * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
   * - it ends with a "/".
   * - it ends with ".lock"
 + * - it contains a "\" (backslash)
   */
  
  static inline int bad_ref_char(int ch)
  {
        if (((unsigned) ch) <= ' ' ||
 -          ch == '~' || ch == '^' || ch == ':')
 +          ch == '~' || ch == '^' || ch == ':' || ch == '\\')
                return 1;
        /* 2.13 Pattern Matching Notation */
        if (ch == '?' || ch == '[') /* Unsupported */
@@@ -751,8 -751,9 +752,8 @@@ int check_ref_format(const char *ref
        }
  }
  
 -const char *prettify_ref(const struct ref *ref)
 +const char *prettify_refname(const char *name)
  {
 -      const char *name = ref->name;
        return name + (
                !prefixcmp(name, "refs/heads/") ? 11 :
                !prefixcmp(name, "refs/tags/") ? 10 :
@@@ -1418,7 -1419,7 +1419,7 @@@ int read_ref_at(const char *ref, unsign
        logfile = git_path("logs/%s", ref);
        logfd = open(logfile, O_RDONLY, 0);
        if (logfd < 0)
 -              die("Unable to read log %s: %s", logfile, strerror(errno));
 +              die_errno("Unable to read log '%s'", logfile);
        fstat(logfd, &st);
        if (!st.st_size)
                die("Log %s is empty.", logfile);