commit 4bff57b4b66990d6829cb83645d1f1d478ae0cea from: Stefan Sperling date: Tue Feb 14 17:06:42 2023 UTC backout got: always fetch remote HEAD except when -b is used As pointed out by naddy, this behaviour is not ideal when users want to limit their repository to a particular branch which will diverge from HEAD over time, such as -stable branches. See https://marc.gameoftrees.org/mail/1676388048.8632_0.html commit - 2a19e2e21a876bbc4ae1999ca08ce4c8f2002158 commit + 4bff57b4b66990d6829cb83645d1f1d478ae0cea blob - ebe6d90a67b21639861c1b8348207f3e18f13847 blob + d9209e2ae1dd1c1aa01e368bc0016cf86830a9e7 --- got/got.1 +++ got/got.1 @@ -348,13 +348,16 @@ file of the local repository, as created by By default, any branches configured in .Xr got.conf 5 for the -.Ar remote-repository , -and the branch resolved via the remote repository's HEAD reference, +.Ar remote-repository will be fetched. If .Cm got fetch is invoked in a work tree then this work tree's current branch will be fetched, too, provided it is present on the server. +If no branches to fetch can be found in +.Xr got.conf 5 +or via a work tree, or said branches are not found on the server, a branch +resolved via the remote repository's HEAD reference will be fetched. This default behaviour can be overridden with the .Fl a and blob - d7765cba2443709b2f200d7c2a3ebca4eb013084 blob + 1ef76ea95b69bf7e45b91f9053a232d241269e7d --- got/got.c +++ got/got.c @@ -1544,7 +1544,7 @@ cmd_clone(int argc, char *argv[]) struct got_fetch_progress_arg fpa; char *git_url = NULL; int verbosity = 0, fetch_all_branches = 0, mirror_references = 0; - int bflag = 0, list_refs_only = 0; + int list_refs_only = 0; int *pack_fds = NULL; TAILQ_INIT(&refs); @@ -1562,7 +1562,6 @@ cmd_clone(int argc, char *argv[]) optarg, NULL); if (error) return error; - bflag = 1; break; case 'l': list_refs_only = 1; @@ -1718,7 +1717,7 @@ cmd_clone(int argc, char *argv[]) error = got_fetch_pack(&pack_hash, &refs, &symrefs, GOT_FETCH_DEFAULT_REMOTE_NAME, mirror_references, fetch_all_branches, &wanted_branches, &wanted_refs, - list_refs_only, verbosity, fetchfd, repo, NULL, bflag, + list_refs_only, verbosity, fetchfd, repo, NULL, 0, fetch_progress, &fpa); if (error) goto done; blob - 990487533727da2e638cbb3271a6802b6af4a80b blob + 2a22df95ff37a15b31f41c7c01f263af824ddc15 --- libexec/got-fetch-pack/got-fetch-pack.c +++ libexec/got-fetch-pack/got-fetch-pack.c @@ -342,12 +342,13 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1, int is_firstpkt = 1, nref = 0, refsz = 16; int i, n, nwant = 0, nhave = 0, acked = 0; off_t packsz = 0, last_reported_packsz = 0; - char *id_str = NULL, *refname = NULL; + char *id_str = NULL, *default_id_str = NULL, *refname = NULL; char *server_capabilities = NULL, *my_capabilities = NULL; const char *default_branch = NULL; struct got_pathlist_head symrefs; struct got_pathlist_entry *pe; int sent_my_capabilites = 0, have_sidebands = 0; + int found_branch = 0; SHA1_CTX sha1_ctx; uint8_t sha1_buf[SHA1_DIGEST_LENGTH]; size_t sha1_buf_len = 0; @@ -438,17 +439,13 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1, } continue; } - - /* always fetch remote HEAD unless -b was specified */ - if (!no_head && default_branch && - strcmp(refname, default_branch) == 0 && - strncmp(default_branch, "refs/heads/", 11) == 0) { - err = fetch_ref(ibuf, have_refs, &have[nref], - &want[nref], default_branch, id_str); - if (err) + if (default_branch && default_id_str == NULL && + strcmp(refname, default_branch) == 0) { + default_id_str = strdup(id_str); + if (default_id_str == NULL) { + err = got_error_from_errno("strdup"); goto done; - nref++; - continue; + } } if (list_refs_only || strncmp(refname, "refs/tags/", 10) == 0) { @@ -464,6 +461,7 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1, if (err) goto done; nref++; + found_branch = 1; continue; } TAILQ_FOREACH(pe, wanted_branches, entry) { @@ -477,6 +475,7 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1, if (err) goto done; nref++; + found_branch = 1; } else if (chattygot) { fprintf(stderr, "%s: ignoring %s\n", getprogname(), refname); @@ -501,6 +500,16 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1, if (list_refs_only) goto done; + + if (!found_branch && !no_head && default_branch && default_id_str && + strncmp(default_branch, "refs/heads/", 11) == 0) { + err = fetch_ref(ibuf, have_refs, &have[nref], + &want[nref], default_branch, default_id_str); + if (err) + goto done; + nref++; + found_branch = 1; + } /* Abort if we haven't found anything to fetch. */ if (nref == 0) { @@ -802,6 +811,7 @@ done: free(have); free(want); free(id_str); + free(default_id_str); free(refname); free(server_capabilities); return err; blob - 5f22ce4442d17056f561112d5ba89fe236f098a4 blob + b5089c370c1eb445b14ae243faad7fb9fefbb907 --- regress/cmdline/fetch.sh +++ regress/cmdline/fetch.sh @@ -211,11 +211,8 @@ test_fetch_branch() { got ref -l -r $testroot/repo-clone > $testroot/stdout echo "HEAD: refs/heads/master" > $testroot/stdout.expected - echo "refs/heads/foo: $commit_id3" >> $testroot/stdout.expected echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected - echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \ - >> $testroot/stdout.expected - echo "refs/remotes/origin/foo: $commit_id3" \ + echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \ >> $testroot/stdout.expected echo "refs/remotes/origin/master: $commit_id2" \ >> $testroot/stdout.expected @@ -1116,12 +1113,9 @@ test_fetch_update_headref() { got ref -l -r $testroot/repo-clone > $testroot/stdout echo "HEAD: refs/heads/master" > $testroot/stdout.expected - echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected - echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected - echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \ + echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected + echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/foo: $commit_id" \ - >> $testroot/stdout.expected echo "refs/remotes/origin/master: $commit_id" \ >> $testroot/stdout.expected @@ -1432,7 +1426,7 @@ test_fetch_delete_remote_refs() { } test_fetch_honor_wt_conf_bflag() { - local testroot=`test_init fetch_honor_wt_conf_bflag` + local testroot=`test_init fetch_branch` local testurl=ssh://127.0.0.1/$testroot # server will have 'boo', 'hoo', and 'master' @@ -1502,15 +1496,11 @@ test_fetch_honor_wt_conf_bflag() { return 1 fi - (cd $testroot/repo && git checkout -q master) - echo "alpha master" > $testroot/repo/alpha - git_commit $testroot/repo -m "alpha master" - local commit_id_alpha_master=`git_show_head $testroot/repo` - (cd $testroot/repo && git checkout -q boo) - - # from repo: no -b used, fetch got.conf "master" and repo HEAD "boo" - got fetch -q -r $testroot/repo-clone > $testroot/stdout + # from repo: fetch got.conf branch not repo HEAD + # boo is the default HEAD in $testroot/repo, which is not up-to-date + # on the clone, but we fetch got.conf "master" which is up-to-date + got fetch -r $testroot/repo-clone > $testroot/stdout ret=$? if [ $ret -ne 0 ]; then echo "got fetch command failed unexpectedly" >&2 @@ -1518,19 +1508,9 @@ test_fetch_honor_wt_conf_bflag() { return 1 fi - got ref -l -r $testroot/repo-clone > $testroot/stdout - - echo "HEAD: refs/heads/master" > $testroot/stdout.expected - echo "refs/heads/bar: $commit_id" >> $testroot/stdout.expected - echo "refs/heads/boo: $commit_id2" >> $testroot/stdout.expected - echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected - echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected - echo "refs/remotes/origin/HEAD: refs/remotes/origin/boo" \ - >> $testroot/stdout.expected - echo "refs/remotes/origin/boo: $commit_id2" \ - >> $testroot/stdout.expected - echo "refs/remotes/origin/master: $commit_id_alpha_master" \ - >> $testroot/stdout.expected + echo "Connecting to \"origin\" ssh://127.0.0.1$testroot/repo" \ + > $testroot/stdout.expected + echo "Already up-to-date" >> $testroot/stdout.expected cmp -s $testroot/stdout $testroot/stdout.expected ret=$? @@ -1563,17 +1543,14 @@ test_fetch_honor_wt_conf_bflag() { echo "HEAD: refs/heads/master" > $testroot/stdout.expected echo "refs/heads/bar: $commit_id" >> $testroot/stdout.expected - echo "refs/heads/boo: $commit_id2" >> $testroot/stdout.expected echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected echo "refs/heads/hoo: $commit_id3" >> $testroot/stdout.expected echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected - echo "refs/remotes/origin/HEAD: refs/remotes/origin/boo" \ + echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/boo: $commit_id2" \ - >> $testroot/stdout.expected echo "refs/remotes/origin/hoo: $commit_id3" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/master: $commit_id_alpha_master" \ + echo "refs/remotes/origin/master: $commit_id" \ >> $testroot/stdout.expected cmp -s $testroot/stdout $testroot/stdout.expected @@ -1612,15 +1589,11 @@ test_fetch_honor_wt_conf_bflag() { return 1 fi - # from repo: fetch got.conf branch "foo", which - # doesn't exist on the server, and repo HEAD "boo" + # from repo: fetch got.conf branch which doesn't exist, so fallback + # to repo HEAD "boo" # change default branch in got.conf from "master" to "foo" sed -i "s/master/foo/" $testroot/repo-clone/got.conf - echo "modified alpha again on boo" > $testroot/repo/alpha - git_commit $testroot/repo -m "modified alpha again on boo" - commit_id_alpha=`git_show_head $testroot/repo` - got fetch -q -r $testroot/repo-clone > $testroot/stdout ret=$? if [ $ret -ne 0 ]; then @@ -1649,11 +1622,11 @@ test_fetch_honor_wt_conf_bflag() { echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected echo "refs/remotes/origin/HEAD: refs/remotes/origin/boo" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/boo: $commit_id_alpha" \ + echo "refs/remotes/origin/boo: $commit_id2" \ >> $testroot/stdout.expected echo "refs/remotes/origin/hoo: $commit_id3" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/master: $commit_id_alpha_master" \ + echo "refs/remotes/origin/master: $commit_id" \ >> $testroot/stdout.expected cmp -s $testroot/stdout $testroot/stdout.expected @@ -1664,16 +1637,13 @@ test_fetch_honor_wt_conf_bflag() { return 1 fi - # from wt: fetch got.conf "foo", which doesn't exist on the - # server, and implicit wt branch "boo", and repo HEAD "master" + # from wt: fetch got.conf "foo", which doesn't exist on the server, + # and implicit wt branch "boo", not repo HEAD "master" echo "modified delta on boo" > $testroot/repo/gamma/delta git_commit $testroot/repo -m "modified delta" local commit_id4=`git_show_head $testroot/repo` (cd $testroot/repo && git checkout -q master) - echo "modified zeta on master" > $testroot/repo/epsilon/zeta - git_commit $testroot/repo -m "modified zeta on master" - local commit_id_zeta=`git_show_head $testroot/repo` got checkout -b boo $testroot/repo-clone $testroot/wt > /dev/null (cd $testroot/wt && got fetch -q > $testroot/stdout) @@ -1707,7 +1677,7 @@ test_fetch_honor_wt_conf_bflag() { >> $testroot/stdout.expected echo "refs/remotes/origin/hoo: $commit_id3" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/master: $commit_id_zeta" \ + echo "refs/remotes/origin/master: $commit_id" \ >> $testroot/stdout.expected cmp -s $testroot/stdout $testroot/stdout.expected @@ -1718,7 +1688,7 @@ test_fetch_honor_wt_conf_bflag() { return 1 fi - # from wt: fetch got.conf "master" and wt "boo", and repo HEAD "hoo" + # from wt: fetch got.conf "master" and wt "boo", not repo HEAD "hoo" # change default branch in got.conf from "foo" to "master" sed -i "s/foo/master/" $testroot/repo-clone/got.conf echo "modified delta on master" > $testroot/repo/gamma/delta @@ -1761,7 +1731,7 @@ test_fetch_honor_wt_conf_bflag() { >> $testroot/stdout.expected echo "refs/remotes/origin/boo: $commit_id6" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/hoo: $commit_id7" \ + echo "refs/remotes/origin/hoo: $commit_id3" \ >> $testroot/stdout.expected echo "refs/remotes/origin/master: $commit_id5" \ >> $testroot/stdout.expected @@ -1776,10 +1746,6 @@ test_fetch_honor_wt_conf_bflag() { # from wt: fetch -b hoo not got.conf "master" or wt "boo" or # repo HEAD "boo" - echo "hoo delta!" > $testroot/repo/gamma/delta - git_commit $testroot/repo -m "hoo delta!" - local commit_id_delta=`git_show_head $testroot/repo` - (cd $testroot/repo && git checkout -q boo) echo "modified alpha again on boo" > $testroot/repo/alpha git_commit $testroot/repo -m "modified alpha again on boo" @@ -1811,7 +1777,7 @@ test_fetch_honor_wt_conf_bflag() { >> $testroot/stdout.expected echo "refs/remotes/origin/boo: $commit_id6" \ >> $testroot/stdout.expected - echo "refs/remotes/origin/hoo: $commit_id_delta" \ + echo "refs/remotes/origin/hoo: $commit_id7" \ >> $testroot/stdout.expected echo "refs/remotes/origin/master: $commit_id5" \ >> $testroot/stdout.expected