summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Elijah Newren <newren@gmail.com>2022-02-02 02:37:29 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2022-02-02 10:02:27 -0800
commit7b90ab467a658b2fb1b7c15c7d634e06f35f4ef2 (patch)
tree223e2be7ced848f782226bc6bd984f065f0cf546
parentshow, log: provide a --remerge-diff capability (diff)
downloadtgif-7b90ab467a658b2fb1b7c15c7d634e06f35f4ef2.tar.xz
log: clean unneeded objects during `log --remerge-diff`
The --remerge-diff option will need to create new blobs and trees representing the "automatic merge" state. If one is traversing a long project history, one can easily get hundreds of thousands of loose objects generated during `log --remerge-diff`. However, none of those loose objects are needed after we have completed our diff operation; they can be summarily deleted. Add a new helper function to tmp_objdir to discard all the contained objects, and call it after each merge is handled. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/log.c13
-rw-r--r--log-tree.c8
-rw-r--r--revision.h3
-rw-r--r--tmp-objdir.c5
-rw-r--r--tmp-objdir.h6
5 files changed, 28 insertions, 7 deletions
diff --git a/builtin/log.c b/builtin/log.c
index a7d624f4a7..63d480b37b 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -422,13 +422,12 @@ static int cmd_log_walk(struct rev_info *rev)
struct commit *commit;
int saved_nrl = 0;
int saved_dcctc = 0;
- struct tmp_objdir *remerge_objdir = NULL;
if (rev->remerge_diff) {
- remerge_objdir = tmp_objdir_create("remerge-diff");
- if (!remerge_objdir)
+ rev->remerge_objdir = tmp_objdir_create("remerge-diff");
+ if (!rev->remerge_objdir)
die(_("unable to create temporary object directory"));
- tmp_objdir_replace_primary_odb(remerge_objdir, 1);
+ tmp_objdir_replace_primary_odb(rev->remerge_objdir, 1);
}
if (rev->early_output)
@@ -473,8 +472,10 @@ static int cmd_log_walk(struct rev_info *rev)
rev->diffopt.no_free = 0;
diff_free(&rev->diffopt);
- if (rev->remerge_diff)
- tmp_objdir_destroy(remerge_objdir);
+ if (rev->remerge_diff) {
+ tmp_objdir_destroy(rev->remerge_objdir);
+ rev->remerge_objdir = NULL;
+ }
if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
rev->diffopt.flags.check_failed) {
diff --git a/log-tree.c b/log-tree.c
index 8f762fb373..6b62ae1a6b 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -4,6 +4,7 @@
#include "diff.h"
#include "object-store.h"
#include "repository.h"
+#include "tmp-objdir.h"
#include "commit.h"
#include "tag.h"
#include "graph.h"
@@ -946,7 +947,12 @@ static int do_remerge_diff(struct rev_info *opt,
strbuf_release(&parent1_desc);
strbuf_release(&parent2_desc);
merge_finalize(&o, &res);
- /* TODO: clean up the temporary object directory */
+
+ /* Clean up the contents of the temporary object directory */
+ if (opt->remerge_objdir)
+ tmp_objdir_discard_objects(opt->remerge_objdir);
+ else
+ BUG("did a remerge diff without remerge_objdir?!?");
return !opt->loginfo;
}
diff --git a/revision.h b/revision.h
index 13178e6b8f..44efce3f41 100644
--- a/revision.h
+++ b/revision.h
@@ -318,6 +318,9 @@ struct rev_info {
/* misc. flags related to '--no-kept-objects' */
unsigned keep_pack_cache_flags;
+
+ /* Location where temporary objects for remerge-diff are written. */
+ struct tmp_objdir *remerge_objdir;
};
int ref_excluded(struct string_list *, const char *path);
diff --git a/tmp-objdir.c b/tmp-objdir.c
index 3d38eeab66..adf6033549 100644
--- a/tmp-objdir.c
+++ b/tmp-objdir.c
@@ -79,6 +79,11 @@ static void remove_tmp_objdir_on_signal(int signo)
raise(signo);
}
+void tmp_objdir_discard_objects(struct tmp_objdir *t)
+{
+ remove_dir_recursively(&t->path, REMOVE_DIR_KEEP_TOPLEVEL);
+}
+
/*
* These env_* functions are for setting up the child environment; the
* "replace" variant overrides the value of any existing variable with that
diff --git a/tmp-objdir.h b/tmp-objdir.h
index cda5ec7677..76efc7edee 100644
--- a/tmp-objdir.h
+++ b/tmp-objdir.h
@@ -47,6 +47,12 @@ int tmp_objdir_migrate(struct tmp_objdir *);
int tmp_objdir_destroy(struct tmp_objdir *);
/*
+ * Remove all objects from the temporary object directory, while leaving it
+ * around so more objects can be added.
+ */
+void tmp_objdir_discard_objects(struct tmp_objdir *);
+
+/*
* Add the temporary object directory as an alternate object store in the
* current process.
*/