I realize there are already questions on how to back up a repository (and the answer is usually git bundle
), but I'd aiming specific setup.
I'd trying to periodically commit a "snapshot" of the current branch to another branch for backup purposes. I'm using a batch file, and it looks like this (I've tried more variations than I can list here):
git stash
git checkout backup
git add .
git commit -m "Automatic Backup %Time%"
git push --all origin
git stash pop
git checkout -
The behavior I'm aiming for is that each commit should be an exact snapshot of the current state of the directory, regardless of what branch I have checked out when I run it. If a newer commit changes a file, I want it to take precedence if a merge conflict arises.
I'm not actually trying to merge branches, I'm just trying to get the files as they exist at the time of the snapshot on the disk. So if branch A has a change on file A, and branch B has a conflicting change on the same file, but branch B is checked out, the backup branch should end up getting branch B's changes, which are currently in the file on the disk, ignoring anything else.
And a practical(?) example of what I'm trying to do: Say Branch A has "myfile.txt" as "Hello World", and Branch B has "myfile.txt" as "Hello Dave".
When I checkout Branch A and open "myfile.txt" in a text editor I expect it'd have "Hello World". When I checkout B, I'd expect it to have "Hello Dave".
If within one branch commit 1 had "Hello World", and 2 had "Hello Dave" there wouldn't be a conflict. I want my back up branch to end up with commit 1 containing "Hello World", and commit 2 containing "Hello Dave" assuming commit 1 occurred while I had previously checked out branch A, and branch B when commit 2 occurred.
I believe git stash is the key to what I'm doing, but it simply isn't working. I tried several different combinations of those commands, and all of them returned different variations off errors, at different points while the repo was in various states, so it's really hard to summarize them. I'd say my approach is probably fundamentally wrong, so the commands listed are there just to give a picture of what I've tried so far.
But no matter what I do I either get merge conflicts or nothing gets committed. What am I missing? (If there's any additional information I can provide, please let me know)
It seems to me that you want to automatically backup the working directory contents as a new commit in the backup
branch and the push all the branches to origin
.
In that case, you do not want to checkout
the backup
branch because that would change your working directory contents. Instead, you'll want to use some combination of git read-tree
, git update-index
and git commit-tree
to fabricate a new commit for your backup
branch and then use git branch -f
to add the newly fabricated commit to the backup
branch. After that, you can continue to do the regular push to origin
.
Links: http://alx.github.io/gitbook/7_raw_git.html
Update:
I think the easiest way to do this is like this (assuming you already have a branch called backup
):
#!/bin/bash
BRANCH=backup
export GIT_INDEX_FILE=/tmp/git-backup-index.$$
git add .
git commit-tree $(git write-tree) -p $(git show-ref --hash --heads $BRANCH) -m "Automatic backup" | xargs git branch -f $BRANCH
rm -f "$GIT_INDEX_FILE"
#git push origin $BRANCH
(Note that I haven't tested the above script...)