26

What I'm trying to do: test pull requests from github. I want to locally merge a pull request into master and run some tests on the result. Since the repository is huge, I do a shallow clone.

To be able to do the merge, I fetch more and more commits (git fetch with increasing --depth) until I have the merge-commit between master the pull request.

However, it doesn't work every time. It looks like I do not only need the merge-base, but also every commit in the master..merge_base range. I'm not sure however how to do that.

So, the question is: how do I fetch enough history to do the merge?

madjar
  • 12,081
  • 2
  • 43
  • 52

2 Answers2

14

If you have the history from when feature branched from master but don't want the full history of master then you can estimate a branching date and use;

git fetch --shallow-since=<date> origin master

It's hard to use any other form of git fetch to do what you want (query the remote for the merge-base) because git fetch fetches refs. There might not be a ref that you're looking for.

You can automate the digging using the following script.

while [ -z $( git merge-base master feature ) ]; do     
    git fetch -q --deepen=1 origin master feature;
done
Adam
  • 3,592
  • 25
  • 29
  • 3
    Doing so many fetches only one level deeper seems awfully inefficient because of network and git packing overhead. Maybe rather use something like `deepen=100`. – fabb May 13 '19 at 16:46
  • @fabb completely agree. Tune as desired. – Adam May 13 '19 at 20:00
  • The second command just infinite loops when I try it ``` usage: git merge-base [-a | --all] ... or: git merge-base [-a | --all] --octopus ... or: git merge-base --independent ... or: git merge-base --is-ancestor or: git merge-base --fork-point [] -a, --all output all common ancestors --octopus find ancestors for a single n-way merge --independent list revs not reachable from others ``` – Zac Sweers Jul 26 '20 at 08:00
  • Note that [`--deepen` requires Git 2.11+ (from 2016)](https://stackoverflow.com/a/39997175/1026). – Nickolay Dec 13 '20 at 17:10
  • The `git fetch --since` doesn't seem to work reliably with merged Git history. It seems to often fetch the wrong branch of history and then you don't have the commit you requested. – Pavel Šimerda Feb 04 '21 at 12:08
3

What you need (I think), in a catch-22 way, is 'git describe --all --first-parent' to tell you the depth of the given commit from the appropriate branch. However I'm not sure how to get that from Github before you do your shallow fetch ;-)

Philip Oakley
  • 12,527
  • 9
  • 46
  • 67
  • 1
    Even in that case, the depth of a commit is computed using the shortest path from the master to the commit, but I (seem to) need all the commit between master and the merge_base, which may be deeper than merge_base. – madjar Nov 21 '14 at 16:45
  • 1
    Ah, yes, I hadn't thought of the full traversal to the merge_base (rather than the shortest path). If you have a merge loop that had lots of small commits that depth could be quite large. Unfortunately the shallow fetch is only limited by a counted depth, rather than any other scheme. And I'm still not sure how to determine the depth anyway! – Philip Oakley Nov 21 '14 at 22:22