Andres A.
Andres A.

Reputation: 1349

"Extract" a branch from commits made under a directory

Is there a way in git to create a branch with only the commits that affected a directory?

For example, given a repo like the following (commit, commit's patch, branch):

g  dir3/file33 (develop)
f  dir1/file12
e  dir2/file22
d  dir2/file21
c  dir1/file11
b  dir3/file32 (master)
a  dir3/file31

Create a branch that looks like:

f' dir1/file12 (feature dir1)
c  dir1/file11
b  dir3/file32 (master)
a  dir3/file31

So far I've thought of doing something like:

git log --right-only --cherry-pick master...develop -- dir1

I think this returns the commits that I need on the new branch, but I don't know how to "extract" a branch with these commits.

Upvotes: 0

Views: 78

Answers (4)

jthill
jthill

Reputation: 60275

If you're selecting commits for the changes they made, you want rebase or cherrypick. For this, it looks like cherrypick's going to be easiest.

git checkout -b feature/dir1 master
git cherry-pick $(git rev-list --reverse master..develop -- dir1)

is the easy way to do it, it won't notice that it could just fast-forward over your commit c but does that really matter? If it does, just swap c's id in for master in the above, but remember to undo that when you go back for the other directory(ies).

Upvotes: 0

David Neiss
David Neiss

Reputation: 8237

Do a git filter branch on your branch. See https://git-scm.com/docs/git-filter-branch for full details. Look at the --subdirectory-filter flag. I was just rereading your problem statement and it looks like you want to filter multiple directories and not just one? If so, it looks like --subdirectory-filter can't be used since you can only specify one directory with it (and it doesn't look like you can specify --subdirectory-filter multiple times, once for each different directory).

Also look at https://github.com/slobobaby/git_filter

Upvotes: 1

kostix
kostix

Reputation: 55453

git subtree split is what you need.

Since some version of Git it's available right away; in older versions it was a script in the "contrib" directory of the Git distribution.

Upvotes: 1

dubes
dubes

Reputation: 5524

Perhaps patching is better suited to your needs.

create patch with the following command:

git diff origin/master HEAD -- <pathToDirectory>/ > changes.patch

Then make your branch however you plan to, hopefully from a commit which is a common ancestor, and apply the patch. Here are the official docs for diff and applying a patch. With this way, if there are conflicts you can easily resolve them.

Upvotes: 0

Related Questions