简体   繁体   中英

Git filter-branch: keep only commits in subdir

How can I edit the history of a branch to keep only commits (and part of commits) that affect a specific sub-directory, from a range of commits?

Basically, I have one big repo with some subdirectories that are fairly, but not entirely, independent. In the past, these have been separate repositories, but this turned out to be problematic, so we merged them into 1 repo. This is fine usually, but after a week of hacking at RoboCup, we want to split up 1 big branch into several smaller ones for easier reviewing and separate pull requests.

I have the subdir challenge_gpsr on branch robocup that I want to create a separate branch for. robocup is branched from 189bd987 and because I'm currently on branch robocup , HEAD points to the final commit in that branch.

Running

git filter-branch -f --index-filter "git rm --ignore-unmatch --cached -qr -- . && git reset -q \$GIT_COMMIT -- challenge_gpsr" --prune-empty -- "robocup" 189bd987..HEAD

Leaves only challenge_gpsr , but that is not what I want, which is to have the other directories as well, but their state should essentially be that at 189bd987 while the following commits only affect subdir challenge_gpsr .

If that works, I repeat this approach for the other subdirs and can review every subdir separately.

I haven't used git filter-branch before and didn't know it existed so thanks for that :D, but I'm pretty sure I can see what's wrong here...

Leaves only challenge_gpsr , but that is not what I want.

That's what I'd expect from your filter command, have a look at each step:

# 1 Remove everything from root-tree (from the new revision)
git rm --ignore-unmatch --cached -qr -- .

# 2 Restore challenge_gpsr sub-tree (from original revision)
git reset -q \$GIT_COMMIT -- challenge_gpsr    

This runs for each revision between 189bd987..HEAD , this will result in the first commit after 189bd987 removing everything outside of challenge_gpsr , after that all commits will only be modifying objects under challenge_gpsr .

...have the other directories as well, but their state should essentially be that at 189bd987

Rather than removing everything, restore the whole tree to 189bd987 then restore the subtree challenge_gpsr from $GIT_COMMIT .

git filter-branch -f --index-filter " \
    git reset -q 189bd987 -- . && \
    git reset -q \$GIT_COMMIT -- challenge_gpsr \
" --prune-empty -- "robocup" 189bd987..HEAD

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM