Skip to content

Commit 2d98446

Browse files
committed
Merge branch 'hv/submodule-find-ff-merge'
* hv/submodule-find-ff-merge: Implement automatic fast-forward merge for submodules setup_revisions(): Allow walking history in a submodule Teach ref iteration module about submodules Conflicts: submodule.c
2 parents d25c72f + 68d03e4 commit 2d98446

File tree

10 files changed

+476
-55
lines changed

10 files changed

+476
-55
lines changed

cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,9 @@ extern char *git_pathdup(const char *fmt, ...)
641641
/* Return a statically allocated filename matching the sha1 signature */
642642
extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
643643
extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
644+
extern char *git_path_submodule(const char *path, const char *fmt, ...)
645+
__attribute__((format (printf, 2, 3)));
646+
644647
extern char *sha1_file_name(const unsigned char *sha1);
645648
extern char *sha1_pack_name(const unsigned char *sha1);
646649
extern char *sha1_pack_index_name(const unsigned char *sha1);

merge-recursive.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "attr.h"
2121
#include "merge-recursive.h"
2222
#include "dir.h"
23+
#include "submodule.h"
2324

2425
static struct tree *shift_tree_object(struct tree *one, struct tree *two,
2526
const char *subtree_shift)
@@ -519,13 +520,15 @@ static void update_file_flags(struct merge_options *o,
519520
void *buf;
520521
unsigned long size;
521522

522-
if (S_ISGITLINK(mode))
523+
if (S_ISGITLINK(mode)) {
523524
/*
524525
* We may later decide to recursively descend into
525526
* the submodule directory and update its index
526527
* and/or work tree, but we do not do that now.
527528
*/
529+
update_wd = 0;
528530
goto update_index;
531+
}
529532

530533
buf = read_sha1_file(sha, &type, &size);
531534
if (!buf)
@@ -710,8 +713,8 @@ static struct merge_file_info merge_file(struct merge_options *o,
710713
free(result_buf.ptr);
711714
result.clean = (merge_status == 0);
712715
} else if (S_ISGITLINK(a->mode)) {
713-
result.clean = 0;
714-
hashcpy(result.sha, a->sha1);
716+
result.clean = merge_submodule(result.sha, one->path, one->sha1,
717+
a->sha1, b->sha1);
715718
} else if (S_ISLNK(a->mode)) {
716719
hashcpy(result.sha, a->sha1);
717720

path.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,44 @@ char *git_path(const char *fmt, ...)
122122
return cleanup_path(pathname);
123123
}
124124

125+
char *git_path_submodule(const char *path, const char *fmt, ...)
126+
{
127+
char *pathname = get_pathname();
128+
struct strbuf buf = STRBUF_INIT;
129+
const char *git_dir;
130+
va_list args;
131+
unsigned len;
132+
133+
len = strlen(path);
134+
if (len > PATH_MAX-100)
135+
return bad_path;
136+
137+
strbuf_addstr(&buf, path);
138+
if (len && path[len-1] != '/')
139+
strbuf_addch(&buf, '/');
140+
strbuf_addstr(&buf, ".git");
141+
142+
git_dir = read_gitfile_gently(buf.buf);
143+
if (git_dir) {
144+
strbuf_reset(&buf);
145+
strbuf_addstr(&buf, git_dir);
146+
}
147+
strbuf_addch(&buf, '/');
148+
149+
if (buf.len >= PATH_MAX)
150+
return bad_path;
151+
memcpy(pathname, buf.buf, buf.len + 1);
152+
153+
strbuf_release(&buf);
154+
len = strlen(pathname);
155+
156+
va_start(args, fmt);
157+
len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
158+
va_end(args);
159+
if (len >= PATH_MAX)
160+
return bad_path;
161+
return cleanup_path(pathname);
162+
}
125163

126164
/* git_mkstemp() - create tmp file honoring TMPDIR variable */
127165
int git_mkstemp(char *path, size_t len, const char *template)

refs.c

Lines changed: 117 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static struct cached_refs {
157157
char did_packed;
158158
struct ref_list *loose;
159159
struct ref_list *packed;
160-
} cached_refs;
160+
} cached_refs, submodule_refs;
161161
static struct ref_list *current_ref;
162162

163163
static struct ref_list *extra_refs;
@@ -229,23 +229,45 @@ void clear_extra_refs(void)
229229
extra_refs = NULL;
230230
}
231231

232-
static struct ref_list *get_packed_refs(void)
232+
static struct ref_list *get_packed_refs(const char *submodule)
233233
{
234-
if (!cached_refs.did_packed) {
235-
FILE *f = fopen(git_path("packed-refs"), "r");
236-
cached_refs.packed = NULL;
234+
const char *packed_refs_file;
235+
struct cached_refs *refs;
236+
237+
if (submodule) {
238+
packed_refs_file = git_path_submodule(submodule, "packed-refs");
239+
refs = &submodule_refs;
240+
free_ref_list(refs->packed);
241+
} else {
242+
packed_refs_file = git_path("packed-refs");
243+
refs = &cached_refs;
244+
}
245+
246+
if (!refs->did_packed || submodule) {
247+
FILE *f = fopen(packed_refs_file, "r");
248+
refs->packed = NULL;
237249
if (f) {
238-
read_packed_refs(f, &cached_refs);
250+
read_packed_refs(f, refs);
239251
fclose(f);
240252
}
241-
cached_refs.did_packed = 1;
253+
refs->did_packed = 1;
242254
}
243-
return cached_refs.packed;
255+
return refs->packed;
244256
}
245257

246-
static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
258+
static struct ref_list *get_ref_dir(const char *submodule, const char *base,
259+
struct ref_list *list)
247260
{
248-
DIR *dir = opendir(git_path("%s", base));
261+
DIR *dir;
262+
const char *path;
263+
264+
if (submodule)
265+
path = git_path_submodule(submodule, "%s", base);
266+
else
267+
path = git_path("%s", base);
268+
269+
270+
dir = opendir(path);
249271

250272
if (dir) {
251273
struct dirent *de;
@@ -261,6 +283,7 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
261283
struct stat st;
262284
int flag;
263285
int namelen;
286+
const char *refdir;
264287

265288
if (de->d_name[0] == '.')
266289
continue;
@@ -270,16 +293,27 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
270293
if (has_extension(de->d_name, ".lock"))
271294
continue;
272295
memcpy(ref + baselen, de->d_name, namelen+1);
273-
if (stat(git_path("%s", ref), &st) < 0)
296+
refdir = submodule
297+
? git_path_submodule(submodule, "%s", ref)
298+
: git_path("%s", ref);
299+
if (stat(refdir, &st) < 0)
274300
continue;
275301
if (S_ISDIR(st.st_mode)) {
276-
list = get_ref_dir(ref, list);
302+
list = get_ref_dir(submodule, ref, list);
277303
continue;
278304
}
279-
if (!resolve_ref(ref, sha1, 1, &flag)) {
305+
if (submodule) {
280306
hashclr(sha1);
281-
flag |= REF_BROKEN;
282-
}
307+
flag = 0;
308+
if (resolve_gitlink_ref(submodule, ref, sha1) < 0) {
309+
hashclr(sha1);
310+
flag |= REF_BROKEN;
311+
}
312+
} else
313+
if (!resolve_ref(ref, sha1, 1, &flag)) {
314+
hashclr(sha1);
315+
flag |= REF_BROKEN;
316+
}
283317
list = add_ref(ref, sha1, flag, list, NULL);
284318
}
285319
free(ref);
@@ -322,10 +356,16 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
322356
for_each_rawref(warn_if_dangling_symref, &data);
323357
}
324358

325-
static struct ref_list *get_loose_refs(void)
359+
static struct ref_list *get_loose_refs(const char *submodule)
326360
{
361+
if (submodule) {
362+
free_ref_list(submodule_refs.loose);
363+
submodule_refs.loose = get_ref_dir(submodule, "refs", NULL);
364+
return submodule_refs.loose;
365+
}
366+
327367
if (!cached_refs.did_loose) {
328-
cached_refs.loose = get_ref_dir("refs", NULL);
368+
cached_refs.loose = get_ref_dir(NULL, "refs", NULL);
329369
cached_refs.did_loose = 1;
330370
}
331371
return cached_refs.loose;
@@ -459,7 +499,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
459499
git_snpath(path, sizeof(path), "%s", ref);
460500
/* Special case: non-existing file. */
461501
if (lstat(path, &st) < 0) {
462-
struct ref_list *list = get_packed_refs();
502+
struct ref_list *list = get_packed_refs(NULL);
463503
while (list) {
464504
if (!strcmp(ref, list->name)) {
465505
hashcpy(sha1, list->sha1);
@@ -588,7 +628,7 @@ int peel_ref(const char *ref, unsigned char *sha1)
588628
return -1;
589629

590630
if ((flag & REF_ISPACKED)) {
591-
struct ref_list *list = get_packed_refs();
631+
struct ref_list *list = get_packed_refs(NULL);
592632

593633
while (list) {
594634
if (!strcmp(list->name, ref)) {
@@ -615,12 +655,12 @@ int peel_ref(const char *ref, unsigned char *sha1)
615655
return -1;
616656
}
617657

618-
static int do_for_each_ref(const char *base, each_ref_fn fn, int trim,
619-
int flags, void *cb_data)
658+
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
659+
int trim, int flags, void *cb_data)
620660
{
621661
int retval = 0;
622-
struct ref_list *packed = get_packed_refs();
623-
struct ref_list *loose = get_loose_refs();
662+
struct ref_list *packed = get_packed_refs(submodule);
663+
struct ref_list *loose = get_loose_refs(submodule);
624664

625665
struct ref_list *extra;
626666

@@ -657,44 +697,89 @@ static int do_for_each_ref(const char *base, each_ref_fn fn, int trim,
657697
return retval;
658698
}
659699

660-
int head_ref(each_ref_fn fn, void *cb_data)
700+
701+
static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)
661702
{
662703
unsigned char sha1[20];
663704
int flag;
664705

706+
if (submodule) {
707+
if (resolve_gitlink_ref(submodule, "HEAD", sha1) == 0)
708+
return fn("HEAD", sha1, 0, cb_data);
709+
710+
return 0;
711+
}
712+
665713
if (resolve_ref("HEAD", sha1, 1, &flag))
666714
return fn("HEAD", sha1, flag, cb_data);
715+
667716
return 0;
668717
}
669718

719+
int head_ref(each_ref_fn fn, void *cb_data)
720+
{
721+
return do_head_ref(NULL, fn, cb_data);
722+
}
723+
724+
int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
725+
{
726+
return do_head_ref(submodule, fn, cb_data);
727+
}
728+
670729
int for_each_ref(each_ref_fn fn, void *cb_data)
671730
{
672-
return do_for_each_ref("refs/", fn, 0, 0, cb_data);
731+
return do_for_each_ref(NULL, "refs/", fn, 0, 0, cb_data);
732+
}
733+
734+
int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
735+
{
736+
return do_for_each_ref(submodule, "refs/", fn, 0, 0, cb_data);
673737
}
674738

675739
int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
676740
{
677-
return do_for_each_ref(prefix, fn, strlen(prefix), 0, cb_data);
741+
return do_for_each_ref(NULL, prefix, fn, strlen(prefix), 0, cb_data);
742+
}
743+
744+
int for_each_ref_in_submodule(const char *submodule, const char *prefix,
745+
each_ref_fn fn, void *cb_data)
746+
{
747+
return do_for_each_ref(submodule, prefix, fn, strlen(prefix), 0, cb_data);
678748
}
679749

680750
int for_each_tag_ref(each_ref_fn fn, void *cb_data)
681751
{
682752
return for_each_ref_in("refs/tags/", fn, cb_data);
683753
}
684754

755+
int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
756+
{
757+
return for_each_ref_in_submodule(submodule, "refs/tags/", fn, cb_data);
758+
}
759+
685760
int for_each_branch_ref(each_ref_fn fn, void *cb_data)
686761
{
687762
return for_each_ref_in("refs/heads/", fn, cb_data);
688763
}
689764

765+
int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
766+
{
767+
return for_each_ref_in_submodule(submodule, "refs/heads/", fn, cb_data);
768+
}
769+
690770
int for_each_remote_ref(each_ref_fn fn, void *cb_data)
691771
{
692772
return for_each_ref_in("refs/remotes/", fn, cb_data);
693773
}
694774

775+
int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
776+
{
777+
return for_each_ref_in_submodule(submodule, "refs/remotes/", fn, cb_data);
778+
}
779+
695780
int for_each_replace_ref(each_ref_fn fn, void *cb_data)
696781
{
697-
return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data);
782+
return do_for_each_ref(NULL, "refs/replace/", fn, 13, 0, cb_data);
698783
}
699784

700785
int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
@@ -734,7 +819,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
734819

735820
int for_each_rawref(each_ref_fn fn, void *cb_data)
736821
{
737-
return do_for_each_ref("refs/", fn, 0,
822+
return do_for_each_ref(NULL, "refs/", fn, 0,
738823
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
739824
}
740825

@@ -958,7 +1043,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
9581043
* name is a proper prefix of our refname.
9591044
*/
9601045
if (missing &&
961-
!is_refname_available(ref, NULL, get_packed_refs(), 0)) {
1046+
!is_refname_available(ref, NULL, get_packed_refs(NULL), 0)) {
9621047
last_errno = ENOTDIR;
9631048
goto error_return;
9641049
}
@@ -1021,7 +1106,7 @@ static int repack_without_ref(const char *refname)
10211106
int fd;
10221107
int found = 0;
10231108

1024-
packed_ref_list = get_packed_refs();
1109+
packed_ref_list = get_packed_refs(NULL);
10251110
for (list = packed_ref_list; list; list = list->next) {
10261111
if (!strcmp(refname, list->name)) {
10271112
found = 1;
@@ -1119,10 +1204,10 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
11191204
if (!symref)
11201205
return error("refname %s not found", oldref);
11211206

1122-
if (!is_refname_available(newref, oldref, get_packed_refs(), 0))
1207+
if (!is_refname_available(newref, oldref, get_packed_refs(NULL), 0))
11231208
return 1;
11241209

1125-
if (!is_refname_available(newref, oldref, get_loose_refs(), 0))
1210+
if (!is_refname_available(newref, oldref, get_loose_refs(NULL), 0))
11261211
return 1;
11271212

11281213
lock = lock_ref_sha1_basic(renamed_ref, NULL, 0, NULL);

refs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ extern int for_each_replace_ref(each_ref_fn, void *);
2828
extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);
2929
extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);
3030

31+
extern int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
32+
extern int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
33+
extern int for_each_ref_in_submodule(const char *submodule, const char *prefix,
34+
each_ref_fn fn, void *cb_data);
35+
extern int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
36+
extern int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
37+
extern int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
38+
3139
static inline const char *has_glob_specials(const char *pattern)
3240
{
3341
return strpbrk(pattern, "?*[");

0 commit comments

Comments
 (0)