Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Wed, 7 Jul 2010 18:18:26 +0000 (11:18 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 7 Jul 2010 18:18:26 +0000 (11:18 -0700)
* maint:
backmerge a few more fixes to 1.7.1.X series
rev-parse: fix --parse-opt --keep-dashdash --stop-at-non-option
fix git branch -m in presence of cross devices

Conflicts:
RelNotes
builtin/rev-parse.c

1  2 
builtin/rev-parse.c
refs.c
t/t1502-rev-parse-parseopt.sh
diff --combined builtin/rev-parse.c
index b676e296357c41cdca2f030d28b511ff986fdad9,95c59fa686de7c8a90ce935aecc35bc83c68076d..a5a1c86e92720e8beefd8275acfc5df2dbdce175
@@@ -407,9 -407,8 +407,9 @@@ static int cmd_parseopt(int argc, cons
        ALLOC_GROW(opts, onb + 1, osz);
        memset(opts + onb, 0, sizeof(opts[onb]));
        argc = parse_options(argc, argv, prefix, opts, usage,
-                       keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0 |
-                       stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0 |
+                       (keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0) |
 -                      (stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0));
++                      (stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0) |
 +                      PARSE_OPT_SHELL_EVAL);
  
        strbuf_addf(&parsed, " --");
        sq_quote_argv(&parsed, argv, 0);
diff --combined refs.c
index 6f486ae62d8b4605520e75286ca36217d0715363,d6307ae29c14d73654039bf8a92483302f4e3e15..b5400674d7a1fcf4cc16dd630b8671b2ad7b9f7b
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -314,11 -314,7 +314,11 @@@ static int warn_if_dangling_symref(cons
  
  void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
  {
 -      struct warn_if_dangling_data data = { fp, refname, msg_fmt };
 +      struct warn_if_dangling_data data;
 +
 +      data.fp = fp;
 +      data.refname = refname;
 +      data.msg_fmt = msg_fmt;
        for_each_rawref(warn_if_dangling_symref, &data);
  }
  
@@@ -1090,6 -1086,15 +1090,15 @@@ int delete_ref(const char *refname, con
        return ret;
  }
  
+ /*
+  * People using contrib's git-new-workdir have .git/logs/refs ->
+  * /some/other/path/.git/logs/refs, and that may live on another device.
+  *
+  * IOW, to avoid cross device rename errors, the temporary renamed log must
+  * live into logs/refs.
+  */
+ #define TMP_RENAMED_LOG  "logs/refs/.tmp-renamed-log"
  int rename_ref(const char *oldref, const char *newref, const char *logmsg)
  {
        static const char renamed_ref[] = "RENAMED-REF";
        if (write_ref_sha1(lock, orig_sha1, logmsg))
                return error("unable to save current sha1 in %s", renamed_ref);
  
-       if (log && rename(git_path("logs/%s", oldref), git_path("tmp-renamed-log")))
-               return error("unable to move logfile logs/%s to tmp-renamed-log: %s",
+       if (log && rename(git_path("logs/%s", oldref), git_path(TMP_RENAMED_LOG)))
+               return error("unable to move logfile logs/%s to "TMP_RENAMED_LOG": %s",
                        oldref, strerror(errno));
  
        if (delete_ref(oldref, orig_sha1, REF_NODEREF)) {
        }
  
   retry:
-       if (log && rename(git_path("tmp-renamed-log"), git_path("logs/%s", newref))) {
+       if (log && rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newref))) {
                if (errno==EISDIR || errno==ENOTDIR) {
                        /*
                         * rename(a, b) when b is an existing
                        }
                        goto retry;
                } else {
-                       error("unable to move logfile tmp-renamed-log to logs/%s: %s",
+                       error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
                                newref, strerror(errno));
                        goto rollback;
                }
                error("unable to restore logfile %s from %s: %s",
                        oldref, newref, strerror(errno));
        if (!logmoved && log &&
-           rename(git_path("tmp-renamed-log"), git_path("logs/%s", oldref)))
-               error("unable to restore logfile %s from tmp-renamed-log: %s",
+           rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldref)))
+               error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s",
                        oldref, strerror(errno));
  
        return 1;
@@@ -1262,65 -1267,52 +1271,65 @@@ static int copy_msg(char *buf, const ch
        return cp - buf;
  }
  
 -static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
 -                       const unsigned char *new_sha1, const char *msg)
 +int log_ref_setup(const char *ref_name, char *logfile, int bufsize)
  {
 -      int logfd, written, oflags = O_APPEND | O_WRONLY;
 -      unsigned maxlen, len;
 -      int msglen;
 -      char log_file[PATH_MAX];
 -      char *logrec;
 -      const char *committer;
 -
 -      if (log_all_ref_updates < 0)
 -              log_all_ref_updates = !is_bare_repository();
 -
 -      git_snpath(log_file, sizeof(log_file), "logs/%s", ref_name);
 +      int logfd, oflags = O_APPEND | O_WRONLY;
  
 +      git_snpath(logfile, bufsize, "logs/%s", ref_name);
        if (log_all_ref_updates &&
            (!prefixcmp(ref_name, "refs/heads/") ||
             !prefixcmp(ref_name, "refs/remotes/") ||
             !prefixcmp(ref_name, "refs/notes/") ||
             !strcmp(ref_name, "HEAD"))) {
 -              if (safe_create_leading_directories(log_file) < 0)
 +              if (safe_create_leading_directories(logfile) < 0)
                        return error("unable to create directory for %s",
 -                                   log_file);
 +                                   logfile);
                oflags |= O_CREAT;
        }
  
 -      logfd = open(log_file, oflags, 0666);
 +      logfd = open(logfile, oflags, 0666);
        if (logfd < 0) {
                if (!(oflags & O_CREAT) && errno == ENOENT)
                        return 0;
  
                if ((oflags & O_CREAT) && errno == EISDIR) {
 -                      if (remove_empty_directories(log_file)) {
 +                      if (remove_empty_directories(logfile)) {
                                return error("There are still logs under '%s'",
 -                                           log_file);
 +                                           logfile);
                        }
 -                      logfd = open(log_file, oflags, 0666);
 +                      logfd = open(logfile, oflags, 0666);
                }
  
                if (logfd < 0)
                        return error("Unable to append to %s: %s",
 -                                   log_file, strerror(errno));
 +                                   logfile, strerror(errno));
        }
  
 -      adjust_shared_perm(log_file);
 +      adjust_shared_perm(logfile);
 +      close(logfd);
 +      return 0;
 +}
 +
 +static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
 +                       const unsigned char *new_sha1, const char *msg)
 +{
 +      int logfd, result, written, oflags = O_APPEND | O_WRONLY;
 +      unsigned maxlen, len;
 +      int msglen;
 +      char log_file[PATH_MAX];
 +      char *logrec;
 +      const char *committer;
 +
 +      if (log_all_ref_updates < 0)
 +              log_all_ref_updates = !is_bare_repository();
 +
 +      result = log_ref_setup(ref_name, log_file, sizeof(log_file));
 +      if (result)
 +              return result;
  
 +      logfd = open(log_file, oflags);
 +      if (logfd < 0)
 +              return 0;
        msglen = msg ? strlen(msg) : 0;
        committer = git_committer_info(0);
        maxlen = strlen(committer) + msglen + 100;
index 434679585555c660f76f42a82f2ff84df3119f01,3b612c67bec5985b24016eff7916942ae0afb58b..b3195c47070b35d555f8cfae90497a2d00d10ca7
@@@ -3,8 -3,7 +3,8 @@@
  test_description='test git rev-parse --parseopt'
  . ./test-lib.sh
  
 -cat > expect.err <<EOF
 +cat > expect <<\END_EXPECT
 +cat <<\EOF
  usage: some-command [options] <args>...
  
      some-command does foo and bar!
@@@ -20,7 -19,6 +20,7 @@@ Extra
      --extra1              line above used to cause a segfault but no longer does
  
  EOF
 +END_EXPECT
  
  cat > optionspec << EOF
  some-command [options] <args>...
@@@ -40,8 -38,8 +40,8 @@@ extra1    line above used to cause a se
  EOF
  
  test_expect_success 'test --parseopt help output' '
 -      git rev-parse --parseopt -- -h 2> output.err < optionspec
 -      test_cmp expect.err output.err
 +      git rev-parse --parseopt -- -h > output < optionspec
 +      test_cmp expect output
  '
  
  cat > expect <<EOF
@@@ -81,4 -79,22 +81,22 @@@ test_expect_success 'test --parseopt --
        test_cmp expect output
  '
  
+ cat >expect <<EOF
+ set -- --foo -- '--' 'arg' '--spam=ham'
+ EOF
+ test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option with --' '
+       git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo -- arg --spam=ham <optionspec >output &&
+       test_cmp expect output
+ '
+ cat > expect <<EOF
+ set -- --foo -- 'arg' '--spam=ham'
+ EOF
+ test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option without --' '
+       git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo arg --spam=ham <optionspec >output &&
+       test_cmp expect output
+ '
  test_done