cache-tree: share code between functions writing an index as a tree
write_tree_from_memory() appeared to be a merge-recursive special that basically duplicated write_index_as_tree(). The two have a different signature, but the bigger difference was just that write_index_as_tree() would always unconditionally read the index off of disk instead of working on the current in-memory index. So: * split out common code into write_index_as_tree_internal() * rename write_tree_from_memory() to write_inmemory_index_as_tree(), make it call write_index_as_tree_internal(), and move it to cache-tree.c Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
Aug 17, 2019 at 11:41 UTC
724dd767b245db588840d7e9dbd46687ee84020b
5 files changed
+67
-58
builtin/checkout.c
+1
-1
@@ -760,7 +760,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
760
*/
761
init_merge_options(&o, the_repository);
762
o.verbosity = 0;
763
- work = write_tree_from_memory(&o);
763
+ work = write_in_core_index_as_tree(the_repository);
764
765
ret = reset_tree(new_tree,
766
opts, 1,
cache-tree.c
+62
-23
@@ -608,11 +608,66 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
608
return it;
609
}
610
611
+static int write_index_as_tree_internal(struct object_id *oid,
612
+ struct index_state *index_state,
613
+ int cache_tree_valid,
614
+ int flags,
615
+ const char *prefix)
616
+{
617
+ if (flags & WRITE_TREE_IGNORE_CACHE_TREE) {
618
+ cache_tree_free(&index_state->cache_tree);
619
+ cache_tree_valid = 0;
620
+ }
621
+
622
+ if (!index_state->cache_tree)
623
+ index_state->cache_tree = cache_tree();
624
+
625
+ if (!cache_tree_valid && cache_tree_update(index_state, flags) < 0)
626
+ return WRITE_TREE_UNMERGED_INDEX;
627
+
628
+ if (prefix) {
629
+ struct cache_tree *subtree;
630
+ subtree = cache_tree_find(index_state->cache_tree, prefix);
631
+ if (!subtree)
632
+ return WRITE_TREE_PREFIX_ERROR;
633
+ oidcpy(oid, &subtree->oid);
634
+ }
635
+ else
636
+ oidcpy(oid, &index_state->cache_tree->oid);
637
+
638
+ return 0;
639
+}
640
+
641
+struct tree* write_in_core_index_as_tree(struct repository *repo) {
642
+ struct object_id o;
643
+ int was_valid, ret;
644
+
645
+ struct index_state *index_state = repo->index;
646
+ was_valid = index_state->cache_tree &&
647
+ cache_tree_fully_valid(index_state->cache_tree);
648
+
649
+ ret = write_index_as_tree_internal(&o, index_state, was_valid, 0, NULL);
650
+ if (ret == WRITE_TREE_UNMERGED_INDEX) {
651
+ int i;
652
+ fprintf(stderr, "BUG: There are unmerged index entries:\n");
653
+ for (i = 0; i < index_state->cache_nr; i++) {
654
+ const struct cache_entry *ce = index_state->cache[i];
655
+ if (ce_stage(ce))
656
+ fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
657
+ (int)ce_namelen(ce), ce->name);
658
+ }
659
+ BUG("unmerged index entries when writing inmemory index");
660
+ }
661
+
662
+ return lookup_tree(repo, &index_state->cache_tree->oid);
663
+}
664
+
665
+
666
int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
667
{
668
int entries, was_valid;
669
struct lock_file lock_file = LOCK_INIT;
615
- int ret = 0;
670
+ int ret;
671
672
hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
673
@@ -621,18 +676,14 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,
676
ret = WRITE_TREE_UNREADABLE_INDEX;
677
goto out;
678
}
624
- if (flags & WRITE_TREE_IGNORE_CACHE_TREE)
625
- cache_tree_free(&index_state->cache_tree);
679
627
- if (!index_state->cache_tree)
628
- index_state->cache_tree = cache_tree();
680
+ was_valid = !(flags & WRITE_TREE_IGNORE_CACHE_TREE) &&
681
+ index_state->cache_tree &&
682
+ cache_tree_fully_valid(index_state->cache_tree);
683
630
- was_valid = cache_tree_fully_valid(index_state->cache_tree);
631
- if (!was_valid) {
632
- if (cache_tree_update(index_state, flags) < 0) {
633
- ret = WRITE_TREE_UNMERGED_INDEX;
634
- goto out;
635
- }
684
+ ret = write_index_as_tree_internal(oid, index_state, was_valid, flags,
685
+ prefix);
686
+ if (!ret && !was_valid) {
687
write_locked_index(index_state, &lock_file, COMMIT_LOCK);
688
/* Not being able to write is fine -- we are only interested
689
* in updating the cache-tree part, and if the next caller
@@ -642,18 +693,6 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,
693
*/
694
}
695
645
- if (prefix) {
646
- struct cache_tree *subtree;
647
- subtree = cache_tree_find(index_state->cache_tree, prefix);
648
- if (!subtree) {
649
- ret = WRITE_TREE_PREFIX_ERROR;
650
- goto out;
651
- }
652
- oidcpy(oid, &subtree->oid);
653
- }
654
- else
655
- oidcpy(oid, &index_state->cache_tree->oid);
656
-
696
out:
697
rollback_lock_file(&lock_file);
698
return ret;
cache-tree.h
+2
-1
@@ -34,7 +34,7 @@ int cache_tree_fully_valid(struct cache_tree *);
34
int cache_tree_update(struct index_state *, int);
35
void cache_tree_verify(struct repository *, struct index_state *);
36
37
-/* bitmasks to write_cache_as_tree flags */
37
+/* bitmasks to write_index_as_tree flags */
38
#define WRITE_TREE_MISSING_OK 1
39
#define WRITE_TREE_IGNORE_CACHE_TREE 2
40
#define WRITE_TREE_DRY_RUN 4
@@ -46,6 +46,7 @@ void cache_tree_verify(struct repository *, struct index_state *);
46
#define WRITE_TREE_UNMERGED_INDEX (-2)
47
#define WRITE_TREE_PREFIX_ERROR (-3)
48
49
+struct tree* write_in_core_index_as_tree(struct repository *repo);
50
int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
51
void prime_cache_tree(struct repository *, struct index_state *, struct tree *);
52
merge-recursive.c
+2
-32
@@ -412,37 +412,6 @@ static void unpack_trees_finish(struct merge_options *opt)
412
clear_unpack_trees_porcelain(&opt->unpack_opts);
413
}
414
415
-struct tree *write_tree_from_memory(struct merge_options *opt)
416
-{
417
- struct tree *result = NULL;
418
- struct index_state *istate = opt->repo->index;
419
-
420
- if (unmerged_index(istate)) {
421
- int i;
422
- fprintf(stderr, "BUG: There are unmerged index entries:\n");
423
- for (i = 0; i < istate->cache_nr; i++) {
424
- const struct cache_entry *ce = istate->cache[i];
425
- if (ce_stage(ce))
426
- fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
427
- (int)ce_namelen(ce), ce->name);
428
- }
429
- BUG("unmerged index entries in merge-recursive.c");
430
- }
431
-
432
- if (!istate->cache_tree)
433
- istate->cache_tree = cache_tree();
434
-
435
- if (!cache_tree_fully_valid(istate->cache_tree) &&
436
- cache_tree_update(istate, 0) < 0) {
437
- err(opt, _("error building trees"));
438
- return NULL;
439
- }
440
-
441
- result = lookup_tree(opt->repo, &istate->cache_tree->oid);
442
-
443
- return result;
444
-}
445
-
415
static int save_files_dirs(const struct object_id *oid,
416
struct strbuf *base, const char *path,
417
unsigned int mode, int stage, void *context)
@@ -3472,7 +3441,8 @@ static int merge_trees_internal(struct merge_options *opt,
3441
3442
unpack_trees_finish(opt);
3443
3475
- if (opt->call_depth && !(*result = write_tree_from_memory(opt)))
3444
+ if (opt->call_depth &&
3445
+ !(*result = write_in_core_index_as_tree(opt->repo)))
3446
return -1;
3447
3448
return clean;
merge-recursive.h
-1
@@ -113,7 +113,6 @@ int merge_recursive_generic(struct merge_options *o,
113
114
void init_merge_options(struct merge_options *o,
115
struct repository *repo);
116
-struct tree *write_tree_from_memory(struct merge_options *o);
116
117
int parse_merge_opt(struct merge_options *out, const char *s);
118