I'm working with a branch that I need to split up in two branches: Commits touching files in a specified list of directories go on one branch, the remaining commits go on the other branch.
Now, my idea was to use interactive rebase for that.
To get the first branch, I'd do this:
git log --format="pick %h %s" --reverse -- <dir-list>
and paste the result of that into the editor opened for the interactive rebase.
But then, to get the second branch, I'd have to maintain the opposite for all the other directories in m开发者_如何学JAVAy repo.
Is there a way to get the list of "opposite commits" somehow, or is there another, easier, solution to my problem?
git log --format="pick %h %s" --reverse -- dir1/ dir2/
could be written
git log --format="pick %h %s" --no-walk \
$(git rev-list --reverse -- dir1/ dir2/)
That is, using
git rev-list HEAD -- dir1/ dir2/
to get the list of 'raw' revision ids. Now to get the complementary set of revision ids, I suggest something like
sort <(git rev-list HEAD) <(git rev-list HEAD -- dir1/ dir2/) | uniq -u
Integrating it all
the complementary set would become
git log --format="pick %h %s" --no-walk \
$(git rev-list --no-walk --reverse \
$(sort <(git rev-list HEAD) \
<(git rev-list HEAD -- dir1/ dir2/) |
uniq -u))
note both --no-walk
parameters there, they are crucial
Recommendations
- I highly recommend making bash functions or scripts to implement the substeps here
- If you are just looking for a way to split repositories, look into git-filter-branch instead!
- it will enable you 'mask' (remove) the unwanted part of the tree for each revision
- allows you to skip effectively empty revisions, like you want
- the man page contains samples for just that
- it will work (correctly) if a single commit edited both parts of the repo
- remember the
--tag-name-filter cat
option
精彩评论