Reputation: 1695
Machine A has Internet connection while machine B does not. Both have local repository and machine A can interact with Github. Development happens on both the machines. git-bundle is being used to keep the repositories in sync.
Usual flow of syncing:
Create a bundle of all the branches in B and transfer the bundle to A.
Clone github repository on A. Pull all branches from bundle into the repository cloned from github. Push the updated repository (all the branches) to github.
Create a bundle of all the branches from github repository. Transfer the bundle to B. Pull all branches from bundle into the repository on B.
There is a way to create a bundle of all the branches of repository. But is there a way to pull all the branches of a bundle into local repository at once?
The two-way sync-up seem to be straight forward in case of single branch repositories.
Upvotes: 4
Views: 3107
Reputation: 3248
Add the following pullbundlebranches git alias to your ~/.gitconfig
and then run git pullbundlebranches ../[filename].gitbundle
.
[alias]
pullbundlebranches = "!f() { git pull --tags $1; git fetch $1; git bundle verify $1 | grep ' refs/heads/' | (while read line; do \
commit=`echo $line | cut -d' ' -f1`; branch=`echo $line | sed 's_[^\\ ]*\\ refs/heads/__'`; \
if git show-ref -q --heads $branch; then \
old_commit=`git rev-parse $branch`; \
if [ \"$old_commit\" = \"$commit\" ]; then \
echo 'Skipping' $branch 'which is up-to-date at' $old_commit; \
elif git merge-base --is-ancestor $branch $commit; then \
current_branch=`git rev-parse --abbrev-ref HEAD`; \
if [ \"$current_branch\" = \"$branch\" ]; then \
git reset --hard $commit; \
else \
git branch -Dq $branch; git branch $branch $commit; \
fi; \
echo 'Updated' $branch 'from' $old_commit 'to' $commit; \
elif git merge-base --is-ancestor $commit $branch; then \
echo 'Skipping' $branch 'which is ahead of bundle version ('$commit')'; \
else \
echo 'Error:' $branch 'already exists and diverges from upstream found in bundle'; \
echo 'You could switch to the bundle version as follows, but you might lose work.'; \
echo 'git checkout -B' $branch $commit; \
fi; \
else \
git branch $branch $commit; \
echo 'Created' $branch 'pointing at' $commit; \
fi; done); }; f"
It fetches from the bundle and then attempts to update/create each branch contained therein. If your own version of the branch is ahead or equal nothing is done. If that branch has diverged from the version in the bundle, an error is printed stating how to switch to the bundle version, and nothing is done.
Example of running, then forcing a branch to the version in the bundle, and then re-running again which does nothing:
$ git pullbundlebranches ../../bundles/Jabberwocky_November_snapshot.gitbundle
From ../../bundles/Jabberwocky_November_snapshot.gitbundle
* branch HEAD -> FETCH_HEAD
../../bundles/Jabberwocky_November_snapshot.gitbundle is okay
Error: develop already exists and diverges from upstream found in bundle
You could switch to the bundle version as follows, but you might lose work.
git checkout -B develop 6c5214a7bd9b10d5f9e49ab9eadaa1533867ebb7
Created feature/all_glory_to_him pointing at 645152be25e0e5d3eb80615c9173e88714b23ade
Created feature/praise_the_lord pointing at 6c5214a7bd9b10d5f9e49ab9eadaa1533867ebb7
Created feature/why_are_you_reading_the_branch_names pointing at a55f5f74d6b129d173770e91c5a0ffe8ff981e8e
$ git checkout -B develop 6c5214a7bd9b10d5f9e49ab9eadaa1533867ebb7
Reset branch 'develop'
Your branch is up to date with 'origin/develop'.
$ git pullbundlebranches ../../bundles/Jabberwocky_November_snapshot.gitbundle
From ../../bundles/Jabberwocky_November_snapshot.gitbundle
* branch HEAD -> FETCH_HEAD
../../bundles/Jabberwocky_November_snapshot.gitbundle is okay
Skipping develop which is up-to-date at 6c5214a7bd9b10d5f9e49ab9eadaa1533867ebb7
Skipping feature/all_glory_to_him which is up-to-date at 645152be25e0e5d3eb80615c9173e88714b23ade
Skipping feature/praise_the_lord which is up-to-date at 6c5214a7bd9b10d5f9e49ab9eadaa1533867ebb7
Skipping feature/why_are_you_reading_the_branch_names which is up-to-date at a55f5f74d6b129d173770e91c5a0ffe8ff981e8e
Upvotes: 1
Reputation: 59963
Since a bundle is just like any other repository – the only difference being that a bundle happens to be stored as a single file – you can use git pull --all
to fetch all branches from the bundle and merge them into their corresponding tracking branches:
git pull --all /path/to/bundle
Note, however, that the --all
option only applies to git fetch
. This means that only the current local branch (i.e. the one referenced by HEAD
) is going to be updated. If you want to also update all local branches, you'll have to write a script for it yourself or use something like git-up.
Upvotes: 0