Enable reflogs by default in any repository with a working directory.
authorShawn O. Pearce <spearce@spearce.org>
Thu, 14 Dec 2006 22:41:17 +0000 (17:41 -0500)
committerJunio C Hamano <junkio@cox.net>
Sat, 16 Dec 2006 06:31:01 +0000 (22:31 -0800)
New and experienced Git users alike are finding out too late that
they forgot to enable reflogs in the current repository, and cannot
use the information stored within it to recover from an incorrectly
entered command such as `git reset --hard HEAD^^^` when they really
meant HEAD^^ (aka HEAD~2).

So enable reflogs by default in all future versions of Git, unless
the user specifically disables it with:

[core]
logAllRefUpdates = false

in their .git/config or ~/.gitconfig.

We only enable reflogs in repositories that have a working directory
associated with them, as shared/bare repositories do not have
an easy means to prune away old log entries, or may fail logging
entirely if the user's gecos information is not valid during a push.
This heuristic was suggested on the mailing list by Junio.

Documentation was also updated to indicate the new default behavior.
We probably should start to teach usuing the reflog to recover
from mistakes in some of the tutorial material, as new users are
likely to make a few along the way and will feel better knowing
they can recover from them quickly and easily, without fsck-objects'
lost+found features.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Documentation/config.txt
builtin-init-db.c
cache.h
environment.c
t/t1400-update-ref.sh
index a3587f83970cf3c7b84b31aa6e90e0dbfb476d65..8abb0820ffdd8e63250d1378fba96dc022de5345 100644 (file)
@@ -79,8 +79,11 @@ core.logAllRefUpdates::
        file is automatically created for branch heads.
 
        This information can be used to determine what commit
-       was the tip of a branch "2 days ago".  This value is
-       false by default (no automated creation of log files).
+       was the tip of a branch "2 days ago".
+
+       This value is true by default in a repository that has
+       a working directory associated with it, and false by
+       default in a bare repository.
 
 core.repositoryFormatVersion::
        Internal variable identifying the repository format and layout
index 8f2b7500dc339a275673c0a0c1b1b3e3e4f5301b..1d7d15e8d53a7a2817ceff6f5c5e056747688c9e 100644 (file)
@@ -242,6 +242,9 @@ static int create_default_files(const char *git_dir, const char *template_path)
                               filemode ? "true" : "false");
        }
 
+       /* Enable logAllRefUpdates if a working tree is attached */
+       if (!is_bare_git_dir(git_dir))
+               git_config_set("core.logallrefupdates", "true");
        return reinit;
 }
 
diff --git a/cache.h b/cache.h
index f2ec5c8c1416e3167d49813965212d414e6a5a7a..2d3df98dc4bee05777c95d0db1ee35b2f74f7996 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -123,6 +123,7 @@ extern int cache_errno;
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
 #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
 
+extern int is_bare_git_dir(const char *dir);
 extern const char *get_git_dir(void);
 extern char *get_object_directory(void);
 extern char *get_refs_directory(void);
index 84d870ca4eca6e202bcbec388e9a299b887f9a12..f8c7dbceadf2190997816f9a21b211a6a97efe48 100644 (file)
@@ -48,6 +48,16 @@ static void setup_git_env(void)
        git_graft_file = getenv(GRAFT_ENVIRONMENT);
        if (!git_graft_file)
                git_graft_file = xstrdup(git_path("info/grafts"));
+       log_all_ref_updates = !is_bare_git_dir(git_dir);
+}
+
+int is_bare_git_dir (const char *dir)
+{
+       const char *s;
+       if (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))
+               return 0;
+       s = strrchr(dir, '/');
+       return !s || strcmp(s + 1, DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
 const char *get_git_dir(void)
index 6a917f2ff48661a5d70fdcbcc700cbf659004818..5637cb5eac2fa77ec3882263418c363a4da8a69a 100755 (executable)
@@ -63,8 +63,8 @@ test_expect_failure \
        "test $B"' = $(cat .git/'"$m"')'
 rm -f .git/$m
 
-mkdir -p .git/logs/refs/heads
-touch .git/logs/refs/heads/master
+: a repository with working tree always has reflog these days...
+: >.git/logs/refs/heads/master
 test_expect_success \
        "create $m (logged by touch)" \
        'GIT_COMMITTER_DATE="2005-05-26 23:30" \