Code

Enable "git rerere" by the config variable rerere.enabled
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Fri, 6 Jul 2007 12:05:59 +0000 (13:05 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 7 Jul 2007 05:39:15 +0000 (22:39 -0700)
Earlier, "git rerere" was enabled by creating the directory
.git/rr-cache.  That is definitely not in line with most other
features, which are enabled by a config variable.

So, check the config variable "rerere.enabled". If it is set
to "false" explicitely, do not activate rerere, even if
.git/rr-cache exists. This should help when you want to disable
rerere temporarily.

If "rerere.enabled" is not set at all, fall back to detection
of the directory .git/rr-cache.

[jc: with minimum tweaks]

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
Documentation/git-rerere.txt
builtin-rerere.c
contrib/emacs/git.el
git-am.sh
git-commit.sh
git-merge.sh
git-rebase.sh
t/t4200-rerere.sh

index 66a55b0514b3a1427792f3e2865f34bc642e1e48..4b67f0adf721d540ddd437254de4aa069f1be0ae 100644 (file)
@@ -448,6 +448,11 @@ gc.rerereunresolved::
        kept for this many days when `git rerere gc` is run.
        The default is 15 days.  See gitlink:git-rerere[1].
 
+rerere.enabled::
+       Activate recording of resolved conflicts, so that identical
+       conflict hunks can be resolved automatically, should they
+       be encountered again.  See gitlink:git-rerere[1].
+
 gitcvs.enabled::
        Whether the cvs server interface is enabled for this repository.
        See gitlink:git-cvsserver[1].
index 7ff9b05e680cabc6513f9d8a6aa80eb7eccda82d..c4d4263238e5b7c6dff705de5d8552a577fc35d6 100644 (file)
@@ -23,7 +23,7 @@ initial manual merge, and later by noticing the same automerge
 results and applying the previously recorded hand resolution.
 
 [NOTE]
-You need to create `$GIT_DIR/rr-cache` directory to enable this
+You need to set the config variable rerere.enabled to enable this
 command.
 
 
@@ -171,7 +171,7 @@ records it if it is a new conflict, or reuses the earlier hand
 resolve when it is not.  `git-commit` also invokes `git-rerere`
 when recording a merge result.  What this means is that you do
 not have to do anything special yourself (Note: you still have
-to create `$GIT_DIR/rr-cache` directory to enable this command).
+to set the config variable rerere.enabled to enable this command).
 
 In our example, when you did the test merge, the manual
 resolution is recorded, and it will be reused when you do the
index 29fb075d29d2deb849e51578e2818d44dbb2a0d5..3196151cc4be4b6fdf6e19735ef26471fc68940f 100644 (file)
@@ -12,6 +12,9 @@ static const char git_rerere_usage[] =
 static int cutoff_noresolve = 15;
 static int cutoff_resolve = 60;
 
+/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
+static int rerere_enabled = -1;
+
 static char *merge_rr_path;
 
 static const char *rr_path(const char *name, const char *file)
@@ -387,21 +390,41 @@ static int git_rerere_config(const char *var, const char *value)
                cutoff_resolve = git_config_int(var, value);
        else if (!strcmp(var, "gc.rerereunresolved"))
                cutoff_noresolve = git_config_int(var, value);
+       else if (!strcmp(var, "rerere.enabled"))
+               rerere_enabled = git_config_bool(var, value);
        else
                return git_default_config(var, value);
        return 0;
 }
 
-int cmd_rerere(int argc, const char **argv, const char *prefix)
+static int is_rerere_enabled(void)
 {
-       struct path_list merge_rr = { NULL, 0, 0, 1 };
-       int i, fd = -1;
        struct stat st;
+       const char *rr_cache;
+       int rr_cache_exists;
 
-       if (stat(git_path("rr-cache"), &st) || !S_ISDIR(st.st_mode))
+       if (!rerere_enabled)
                return 0;
 
+       rr_cache = git_path("rr-cache");
+       rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode);
+       if (rerere_enabled < 0)
+               return rr_cache_exists;
+
+       if (!rr_cache_exists &&
+           (mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache)))
+               die("Could not create directory %s", rr_cache);
+       return 1;
+}
+
+int cmd_rerere(int argc, const char **argv, const char *prefix)
+{
+       struct path_list merge_rr = { NULL, 0, 0, 1 };
+       int i, fd = -1;
+
        git_config(git_rerere_config);
+       if (!is_rerere_enabled())
+               return 0;
 
        merge_rr_path = xstrdup(git_path("rr-cache/MERGE_RR"));
        fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 1);
@@ -411,6 +434,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
                return do_plain_rerere(&merge_rr, fd);
        else if (!strcmp(argv[1], "clear")) {
                for (i = 0; i < merge_rr.nr; i++) {
+                       struct stat st;
                        const char *name = (const char *)merge_rr.items[i].util;
                        if (!stat(git_path("rr-cache/%s", name), &st) &&
                                        S_ISDIR(st.st_mode) &&
index f60017948f4eb45f6aa7fe0fc60ca1507cec98f2..457f95fc0599b32fb6da20c59094cd77d7f6f252 100644 (file)
@@ -681,8 +681,7 @@ and returns the process output as a string."
                             (condition-case nil (delete-file ".git/MERGE_MSG") (error nil))
                             (with-current-buffer buffer (erase-buffer))
                             (git-set-files-state files 'uptodate)
-                            (when (file-directory-p ".git/rr-cache")
-                              (git-run-command nil nil "rerere"))
+                            (git-run-command nil nil "rerere")
                             (git-refresh-files)
                             (git-refresh-ewoc-hf git-status)
                             (message "Committed %s." commit)
index d57a3e2d092c227344deee9596da04e0792f155c..e5e6f2c91c1faf58239ab73672fbb05cda91762f 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -95,10 +95,7 @@ It does not apply to blobs recorded in its index."
     eval GITHEAD_$his_tree='"$SUBJECT"'
     export GITHEAD_$his_tree
     git-merge-recursive $orig_tree -- HEAD $his_tree || {
-           if test -d "$GIT_DIR/rr-cache"
-           then
-               git rerere
-           fi
+           git rerere
            echo Failed to merge in the changes.
            exit 1
     }
@@ -252,10 +249,7 @@ last=`cat "$dotest/last"`
 this=`cat "$dotest/next"`
 if test "$skip" = t
 then
-       if test -d "$GIT_DIR/rr-cache"
-       then
-               git rerere clear
-       fi
+       git rerere clear
        this=`expr "$this" + 1`
        resume=
 fi
@@ -420,10 +414,7 @@ do
                        stop_here_user_resolve $this
                fi
                apply_status=0
-               if test -d "$GIT_DIR/rr-cache"
-               then
-                       git rerere
-               fi
+               git rerere
                ;;
        esac
 
index f866f957c44de4cc72542f34ec1df4ead42256c3..9106a743cc90f532be2c83d3a73799566b95df6a 100755 (executable)
@@ -610,10 +610,7 @@ rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
 
 cd_to_toplevel
 
-if test -d "$GIT_DIR/rr-cache"
-then
-       git rerere
-fi
+git rerere
 
 if test "$ret" = 0
 then
index 485253032adf002f9c5845091b5e93aa50f26b80..5ccf28251d51d3ee10675d48cf04829f5d6d8c06 100755 (executable)
@@ -496,9 +496,6 @@ Conflicts:
                sed -e 's/^[^   ]*      /       /' |
                uniq
        } >>"$GIT_DIR/MERGE_MSG"
-       if test -d "$GIT_DIR/rr-cache"
-       then
-               git rerere
-       fi
+       git rerere
        die "Automatic merge failed; fix conflicts and then commit the result."
 fi
index 7a02f2975d443cfe35c98d3c62b656850d7d406c..cbafa14ed524212441ba76e1bdb558585795e2f3 100755 (executable)
@@ -101,7 +101,7 @@ call_merge () {
                return
                ;;
        1)
-               test -d "$GIT_DIR/rr-cache" && git rerere
+               git rerere
                die "$RESOLVEMSG"
                ;;
        2)
@@ -160,10 +160,7 @@ do
        --skip)
                if test -d "$dotest"
                then
-                       if test -d "$GIT_DIR/rr-cache"
-                       then
-                               git rerere clear
-                       fi
+                       git rerere clear
                        prev_head="`cat $dotest/prev_head`"
                        end="`cat $dotest/end`"
                        msgnum="`cat $dotest/msgnum`"
@@ -181,10 +178,7 @@ do
                exit
                ;;
        --abort)
-               if test -d "$GIT_DIR/rr-cache"
-               then
-                       git rerere clear
-               fi
+               git rerere clear
                if test -d "$dotest"
                then
                        rm -r "$dotest"
index 71d364ab79f5ec971a4d8b26422a3ea78e5f55da..6f55ba03bd36d25c45224688f29b36e8d7734fe0 100755 (executable)
@@ -39,15 +39,32 @@ sed -e 's/To die, t/To die! T/' > a1
 echo "* END *" >>a1
 git commit -q -a -m second
 
-# activate rerere
-mkdir .git/rr-cache
+test_expect_success 'nothing recorded without rerere' '
+       (rm -rf .git/rr-cache; git config rerere.enabled false) &&
+       ! git merge first &&
+       ! test -d .git/rr-cache
+'
 
-test_expect_failure 'conflicting merge' 'git pull . first'
+# activate rerere, old style
+test_expect_success 'conflicting merge' '
+       git reset --hard &&
+       mkdir .git/rr-cache &&
+       git config --unset rerere.enabled &&
+       ! git merge first
+'
 
 sha1=$(sed -e 's/      .*//' .git/rr-cache/MERGE_RR)
 rr=.git/rr-cache/$sha1
 test_expect_success 'recorded preimage' "grep ======= $rr/preimage"
 
+test_expect_success 'rerere.enabled works, too' '
+       rm -rf .git/rr-cache &&
+       git config rerere.enabled true &&
+       git reset --hard &&
+       ! git merge first &&
+       grep ======= $rr/preimage
+'
+
 test_expect_success 'no postimage or thisimage yet' \
        "test ! -f $rr/postimage -a ! -f $rr/thisimage"