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

[PATCH 03/24] read-cache.c: new flag for add_index_entry() to write to backup log

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

Index update API is updated to write to backup log if requested. The entry deletion API is not updated because file removal is not "interesting" from the undo point of view.

Note, we do double locking when writing $GIT_DIR/index now:
- $GIT_DIR/index.lock is created
- then $GIT_DIR/index.bkl.lock is created

Nobody will lock these in reverse order so no chance for dead lock (yet)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h      |  2 ++
 read-cache.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/cache.h b/cache.h
index ca36b44ee0..51ffae7961 100644
--- a/cache.h
+++ b/cache.h
@@ -336,6 +336,7 @@ struct index_state {
 	uint64_t fsmonitor_last_update;
 	struct ewah_bitmap *fsmonitor_dirty;
 	struct mem_pool *ce_mem_pool;
+	struct strbuf *backup_log;
 };
 
 extern struct index_state the_index;
@@ -745,6 +746,7 @@ extern int index_name_pos(const struct index_state *, const char *name, int name
 #define ADD_CACHE_JUST_APPEND 8		/* Append only; tree.c::read_tree() */
 #define ADD_CACHE_NEW_ONLY 16		/* Do not replace existing ones */
 #define ADD_CACHE_KEEP_CACHE_TREE 32	/* Do not invalidate cache-tree */
+#define ADD_CACHE_LOG_UPDATES 64	/* Log changes in $GIT_DIR/index.bkl */
 extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option);
 extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name);
 
diff --git a/read-cache.c b/read-cache.c
index bd45dc3e24..a53cfabc2e 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -25,6 +25,7 @@
 #include "fsmonitor.h"
 #include "thread-utils.h"
 #include "progress.h"
+#include "backup-log.h"
 
 /* Mask for the name length in ce_flags in the on-disk index */
 
@@ -691,6 +692,21 @@ void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
 	oidcpy(&ce->oid, &oid);
 }
 
+static void update_backup_log(struct index_state *istate,
+			      const struct object_id *prev,
+			      const struct cache_entry *ce)
+{
+	struct strbuf *sb = istate->backup_log;
+
+	if (!sb) {
+		sb = xmalloc(sizeof(*sb));
+		strbuf_init(sb, 0);
+		istate->backup_log = sb;
+	}
+
+	bkl_append(sb, ce->name, prev, &ce->oid);
+}
+
 int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
 {
 	int namelen, was_same;
@@ -765,6 +781,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 			discard_cache_entry(ce);
 			return error("unable to index file %s", path);
 		}
+		add_option |= flags & ADD_CACHE_LOG_UPDATES;
 	} else
 		set_object_name_for_intent_to_add_entry(ce);
 
@@ -1257,6 +1274,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
 	int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
 	int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
 	int new_only = option & ADD_CACHE_NEW_ONLY;
+	struct object_id backup_prev;
 
 	if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
 		cache_tree_invalidate_path(istate, ce->name);
@@ -1273,8 +1291,12 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
 
 	/* existing match? Just replace it. */
 	if (pos >= 0) {
-		if (!new_only)
-			replace_index_entry(istate, pos, ce);
+		if (new_only)
+			return 0;
+
+		if (option & ADD_CACHE_LOG_UPDATES)
+			update_backup_log(istate, &istate->cache[pos]->oid, ce);
+		replace_index_entry(istate, pos, ce);
 		return 0;
 	}
 	pos = -pos-1;
@@ -1282,6 +1304,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
 	if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
 		untracked_cache_add_to_index(istate, ce->name);
 
+	oidclr(&backup_prev);
 	/*
 	 * Inserting a merged entry ("stage 0") into the index
 	 * will always replace all non-merged entries..
@@ -1289,6 +1312,8 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
 	if (pos < istate->cache_nr && ce_stage(ce) == 0) {
 		while (ce_same_name(istate->cache[pos], ce)) {
 			ok_to_add = 1;
+			if (ce_stage(ce) == 2)
+				oidcpy(&backup_prev, &istate->cache[pos]->oid);
 			if (!remove_index_entry_at(istate, pos))
 				break;
 		}
@@ -1307,6 +1332,8 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
 		pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce));
 		pos = -pos-1;
 	}
+	if (option & ADD_CACHE_LOG_UPDATES)
+		update_backup_log(istate, &backup_prev, ce);
 	return pos + 1;
 }
 
@@ -2323,6 +2350,10 @@ int discard_index(struct index_state *istate)
 	discard_split_index(istate);
 	free_untracked_cache(istate->untracked);
 	istate->untracked = NULL;
+	if (istate->backup_log) {
+		strbuf_release(istate->backup_log);
+		FREE_AND_NULL(istate->backup_log);
+	}
 
 	if (istate->ce_mem_pool) {
 		mem_pool_discard(istate->ce_mem_pool, should_validate_cache_entries());
@@ -3157,6 +3188,20 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
 	if (istate->fsmonitor_last_update)
 		fill_fsmonitor_bitmap(istate);
 
+	if (istate->backup_log && istate->backup_log->len) {
+		struct strbuf sb = STRBUF_INIT;
+		char *path = get_locked_file_path(lock);
+
+		strbuf_addf(&sb, "%s.bkl", path);
+		free(path);
+		if (bkl_write(sb.buf, istate->backup_log)) {
+			strbuf_release(&sb);
+			return -1;
+		}
+		strbuf_reset(istate->backup_log);
+		strbuf_release(&sb);
+	}
+
 	if (!si || alternate_index_output ||
 	    (istate->cache_changed & ~EXTMASK)) {
 		if (si)
-- 
2.20.0.rc2.486.g9832c05c3d
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 4 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.