I'm running into a problem whereby I want to synch 2 repositories that are not connected via network. I have used git bundle to synch between the two, but have run into a corner case.
I'm creating the git bundle via:
git bundle create --since=<timestamp of lastBundle> --all <my_bundle_path>
where <timestamp of lastBundle>
was picked from the commit time associated with the lastBundle
tag. This allows me to only bundle the delta and pick up all new commits across all branches.
The corner case is when this particular scenario occurs
master 2017-12-4 <dev who committed c2 finally gets around to pushing it to origin>
|\
| \
| c3 <lastBundle> 2017-12-3 <commit that was synched>
| |
c2 | 2017-12-2 <commit from dev, timestamped to when s/he committed it to their local repo>
\ |
\ |
c1 2017-12-1 <base commit>
lastBundle
was synced, and corresponds to the most current reference of the airgapped repo, but someone had committed c2
earlier in time than c3
in their own local copy of the repo and didn't push the reference to origin immediately. Thus, the next time I bundle every commit from lastBundle
onwards and put it on a drive, load it on the other machine, it fails to validate because c2
is not in the bundle, only its merge to master.
I have looked at git merge-base
to see if I can find a common ancestor, and use that instead. While that can do the job, I think I would need a lastBundle
tag for each and every branch to make it work, since this situation could occur on 0, 1 or more branches at the same time. That seems non-optimal.
Ideally, I think I would like to be able to do a git bundle verify <mybundle>
with respect to a given location in the git history, rather than the whole repository. That way I could verify it will fail before I put it on disk, and just change how far back I go for commits when bundling. Unless there is some other way to what I'm trying to do.
Any ideas?
you should make your bundle not based on time, but on what you actually have sent. Use remote references for this (not tested):
git bundle create foo.bundle --branches
git fetch foo.bundle 'refs/heads/*:refs/remotes/sent/*'
....
git bundle create foo.bundle --branches --not --remotes sent
git fetch...