git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 18/24] refs: keep backup of deleted reflog

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Dec 9, 2018, 10:44 UTC
Message-ID
<20181209104419.12639-19-pclouds@gmail.com>
In-Reply-To
<20181209104419.12639-1-pclouds@gmail.com>

As noted in git-backup-log.txt a long time ago, this is mostly meant for recovering a branch immediately after an accidental deletion.

References from the deleted reflog will not be included in reachability tests and they will be deleted at the next gc. At that point, this deleted reflog becomes useless.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 refs/files-backend.c  | 32 ++++++++++++++++++++++++++++++++
 t/t2080-backup-log.sh | 12 ++++++++++++
 2 files changed, 44 insertions(+)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index dd8abe9185..9afb274075 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -11,6 +11,7 @@
 #include "../dir.h"
 #include "../chdir-notify.h"
 #include "worktree.h"
+#include "backup-log.h"
 
 /*
  * This backend uses the following flags in `ref_update::flags` for
@@ -1873,6 +1874,35 @@ static int files_reflog_exists(struct ref_store *ref_store,
 	return ret;
 }
 
+static void backup_reflog(struct files_ref_store *refs,
+			  const char *reflog_path,
+			  const char *refname)
+{
+	int core_backup_log = 0;
+	struct stat st;
+	struct strbuf line = STRBUF_INIT;
+	struct strbuf path = STRBUF_INIT;
+	struct object_id old, new;
+
+	repo_config_get_bool(the_repository, "core.backuplog",
+			     &core_backup_log);
+	if (!core_backup_log)
+		return;
+	if (ref_type(refname) != REF_TYPE_NORMAL)
+		return;
+	if (lstat(reflog_path, &st) ||
+	    index_path(NULL, &old, reflog_path, &st, HASH_WRITE_OBJECT))
+		return;
+
+	strbuf_addf(&path, "logs/%s", refname);
+	oidclr(&new);
+	bkl_append(&line, path.buf, &old, &new);
+	strbuf_release(&path);
+	mkdir_in_gitdir(git_path("common"));
+	bkl_write(git_path("common/gitdir.bkl"), &line);
+	strbuf_release(&line);
+}
+
 static int files_delete_reflog(struct ref_store *ref_store,
 			       const char *refname)
 {
@@ -1882,6 +1912,7 @@ static int files_delete_reflog(struct ref_store *ref_store,
 	int ret;
 
 	files_reflog_path(refs, &sb, refname);
+	backup_reflog(refs, sb.buf, refname);
 	ret = remove_path(sb.buf);
 	strbuf_release(&sb);
 	return ret;
@@ -2797,6 +2828,7 @@ static int files_transaction_finish(struct ref_store *ref_store,
 		    !(update->flags & REF_IS_PRUNING)) {
 			strbuf_reset(&sb);
 			files_reflog_path(refs, &sb, update->refname);
+			backup_reflog(refs, sb.buf, update->refname);
 			if (!unlink_or_warn(sb.buf))
 				try_remove_empty_parents(refs, update->refname,
 							 REMOVE_EMPTY_PARENTS_REFLOG);
diff --git a/t/t2080-backup-log.sh b/t/t2080-backup-log.sh
index dbd19db757..710df1ec8b 100755
--- a/t/t2080-backup-log.sh
+++ b/t/t2080-backup-log.sh
@@ -178,4 +178,16 @@ test_expect_success 'config --edit makes a backup' '
 	grep $NEW .git/common/gitdir.bkl
 '
 
+test_expect_success 'deleted reflog is kept' '
+	git checkout -b foo &&
+	git commit -am everything-else &&
+	test_commit two &&
+	test_commit three &&
+	git checkout -f master &&
+	OLD=$(git hash-object .git/logs/refs/heads/foo) &&
+	git -c core.backupLog=true branch -D foo &&
+	grep logs/refs/heads/foo .git/common/gitdir.bkl &&
+	grep ^$OLD .git/common/gitdir.bkl
+'
+
 test_done
-- 
2.20.0.rc2.486.g9832c05c3d
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 15 of 25 in “Add backup log”
  1. 00/24 Add backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  2. 01/24 doc: introduce new "backup log" conceptNguyễn Thái Ngọc Duy, Dec 9, 2018
  3. 02/24 backup-log: add "update" subcommandNguyễn Thái Ngọc Duy, Dec 9, 2018
  4. 03/24 read-cache.c: new flag for add_index_entry() to write to backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  5. 04/24 add: support backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  6. 05/24 update-index: support backup log with --keep-backupNguyễn Thái Ngọc Duy, Dec 9, 2018
  7. 08/24 add--interactive: support backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  8. 06/24 commit: support backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  9. 07/24 apply: support backup log with --keep-backupNguyễn Thái Ngọc Duy, Dec 9, 2018
  10. 09/24 backup-log.c: add API for walking backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  11. 11/24 backup-log: add diff commandNguyễn Thái Ngọc Duy, Dec 9, 2018
  12. 10/24 backup-log: add cat commandNguyễn Thái Ngọc Duy, Dec 9, 2018
  13. 12/24 backup-log: add log commandNguyễn Thái Ngọc Duy, Dec 9, 2018
  14. 17/24 config --edit: support backup logNguyễn Thái Ngọc Duy, Dec 9, 2018
  15. 18/24 refs: keep backup of deleted reflogNguyễn Thái Ngọc Duy, Dec 9, 2018
  16. 15/24 backup-log: keep all blob references aroundNguyễn Thái Ngọc Duy, Dec 9, 2018
  17. 19/24 unpack-trees.c: keep backup of ignored files being overwrittenNguyễn Thái Ngọc Duy, Dec 9, 2018
  18. 22/24 am: keep backup of overwritten files on --skip or --abortNguyễn Thái Ngọc Duy, Dec 9, 2018
  19. 21/24 checkout -f: keep backup of overwritten filesNguyễn Thái Ngọc Duy, Dec 9, 2018
  20. 14/24 gc: prune backup logsNguyễn Thái Ngọc Duy, Dec 9, 2018
  21. 23/24 rebase: keep backup of overwritten files on --skip or --abortNguyễn Thái Ngọc Duy, Dec 9, 2018
  22. 24/24 FIXMENguyễn Thái Ngọc Duy, Dec 9, 2018
  23. 20/24 reset --hard: keep backup of overwritten filesNguyễn Thái Ngọc Duy, Dec 9, 2018
  24. 16/24 sha1-file.c: let index_path() accept NULL istateNguyễn Thái Ngọc Duy, Dec 9, 2018
  25. 13/24 backup-log: add prune commandNguyễn Thái Ngọc Duy, Dec 9, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.