]> git.ipfire.org Git - thirdparty/git.git/commitdiff
log: clean unneeded objects during `log --remerge-diff`
authorElijah Newren <newren@gmail.com>
Wed, 2 Feb 2022 02:37:29 +0000 (02:37 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 2 Feb 2022 18:02:27 +0000 (10:02 -0800)
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>
builtin/log.c
log-tree.c
revision.h
tmp-objdir.c
tmp-objdir.h

index a7d624f4a77e4f61ce42e45d8a3f1d8d033b2824..63d480b37b9f7b4fa109f72c2e02c2be14adf92c 100644 (file)
@@ -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) {
index 8f762fb3733e5bf75689c7482e1b9ada3dd3a272..6b62ae1a6b4a7d80361a7c9135ec6f864603d44a 100644 (file)
@@ -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;
 }
index 13178e6b8f3d923ba888bae6db7c1e205072a8d7..44efce3f410cae7f725ccf3b502e01ad9b47b5dd 100644 (file)
@@ -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);
index 3d38eeab66bfb048c20dd3490f92f2a6e15e040b..adf6033549ee7369c370e333a57db18ac8bdf0d6 100644 (file)
@@ -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
index cda5ec7677881c5a47bb5f2ebf3edc3a3140a73c..76efc7edee5be4a9197a242f526c74b05f49802a 100644 (file)
@@ -46,6 +46,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.