How to add a file to the first commit on a git repo?
I have been converting old SVN repos to GIT. I have gotten the branches and tags开发者_运维知识库 to convert. Including making SVN tags real tags in GIT.
However, I would like to add a gitignore to the very first commit in the newly created GIT repo. I want it to be as if the file had always been there. So all the commits that followed (on master or in branches) would now have this file as the parent tree(s) would lead back the the first commit.
It seems that some form of git rebase or git filter-branch --tree-filter is what I need. I have tried each of these but I end up with disconnected branches.
I recently had to modify an early commit because of a problematic typo in the commit message. This works for changing anything about a previous commit. I modified Charles Bailey's answer to Combine the first two commits of a Git repository?
# Go back to the commit you want to change (detach HEAD)
git checkout <sha1_for_commit_to_change>
# Make any changes now (add your new file) then add them to the index
git add <new_files>
# amend the current commit
git commit --amend
# temporarily tag this new commit
# (or you could remember the new commit sha1 manually)
git tag tmp
# go back to the original branch (assume master for this example)
git checkout master
# Replay all the commits after the change onto the new initial commit
git rebase --rebase-merges --onto tmp <sha1_for_commit_to_change>
# remove the temporary tag
git tag -d tmp
Note that this will change all of your commit IDs following the amended commit, so it's not recommended on a public repository. Also, you'll have to recreate all of your tags
Do this on a clean working tree, on a new clone if you wish:
$ git checkout -b withgitignore $firstcommithash
$ git add .gitignore
$ git commit --amend
$ for branch in branch1 branch2 branch3 ... ; do
git checkout $branch
git rebase withgitignore
done
Untested ;)
Assuming that this is a brand new rebuild, then one trick is to start a branch at that first commit and add the gitignore there. You now have the 'right' commit at the head of that branch. Now for the trick - you use the grafts
facility to reorder the perceived commit sequence. A plain git filter-branch
will make it permanent, though the old hierarchy will be still be listed under originals
in refs\info (IIRC).
While this will create an early commit that contains the gitignore file, all the other commits will still be without the gitignore file.
Edit:---------- The git-filter-branch, gives examples:
git filter-branch --tree-filter 'rm filename' HEAD
, and a --index-filter
variant.
You could simply add .gitignore
your .gitignore instead of the remove, and use the --index-filter
so that your work tree is still intact for copying from.
Make sure you have a backup first though ! Report if it works for you.
精彩评论