0

I'm having a problem to move some commit from two projets, the details: - Project 1: Have a single git that regroupe many directories - Project 2: Have the same directories of project 1 but for every directory there is a separated git. The issue is: I have a commit in project one that touch files in 2 directories and plus, and I want to cherry-pick that commit and move every change of every file and commit them to project 2.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Optimmus
  • 55
  • 2
  • 3
  • 12

1 Answers1

0

A cherry-pick grabs the entire commit, and applies the entire commit to your current branch. As I understand your question, you want to take commits that make changes to multiple directories, and cherry pick only a single directory's changes in each commit into a separate git repository that includes that directory only.

Since a cherry-pick, as I said, grabs the entire commit, it will not work like that, by itself.

However, it should be possible to use cherry-pick together with filter-branch in order to achieve this.

The first thing to do is to check out a new working branch in Project 1, so as to not mess up any of its existing branches. You working branch will be a flaming wreck, by the end of this, at which point you can quietly get rid of it; no harm, no foul.

Once in the new working branch, use git filter-branch --tree-filter to rewrite the commits, deleting everything in the tree except for one of the directories in question (you'll have to start the rewrite from the parent of the commit/commits you wish to migrate, rather than the commit/commits itself).

At this point, the rewritten commits will end up touching only the files in a single directory in Project 1 (you also end up with all the other directories completely blown away, in your working branch, but who cares). The parent commit includes the removal of all other directories in the working branch, and all the following commits are limited to changes in the remaining directory. At this point you should be able to cherry-pick these commits into the appropriate git repository for Project 2.

Lather, rinse, and repeat for every such directory that you are attempting to migrate.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Thank you Sam for your reply, i'm testing it, but i never worked with git filter-branch --tree-filter, i have an example and tell your solution: - In project 1: i have commit b0cefe4de84, that make changes in: - frameworks/base/LockPatternUtils.java - packages/apps/Settings/security_finger_picker.xml - packages/apps/Mms/SecuritySettings.java - In project 2: i have theses git: - (frameworks-base) frameworks/base - (packages-apps-Settings) packages/apps/Settings/ - (packages-apps-Mms) packages/apps/Mms – Optimmus Jun 23 '16 at 11:20
  • Well, now's your opportunity to learn how to filter branches. You should find plenty of information in git's documentation and Google searches. Stackoverflow is not a tutorial site, even if it were, a 400 character comment isn't enough for any tutorial. – Sam Varshavchik Jun 23 '16 at 11:45
  • Thanks for your reply, effectively you are right, i already looked for more deeply information in git, and i did this command-line : git filter-branch --tree-filter 'rm -r !(frameworks/base)' b0cefe4de84^..HEAD where will keep framework/base and delete the remaining files in the commit, but you want i have error git-filter-branch: 1: eval: Syntax error: "(" unexpected, anyway, why you want to "start the rewrite from the parent of the commit/commits you wish to migrate, rather than the commit/commits itself)." ? – Optimmus Jun 23 '16 at 12:40
  • I explained this in my answer. If you start with the commit itself, the commit itself will be changed to remove all other directories, as part of the commit, and you still will not be able to cherry pick it. You want the rewritten branch's previous commit to do that, so that the commit itself, that you want to cherry-pick, is left with only the changes to the remaining directory. If you were to try to execute `rm -r !(frameworks/base)` manually, from the shell, you will get the same error. Figure out the correct command to remove the unwanted directories, first, then use `git filter-branch` – Sam Varshavchik Jun 23 '16 at 12:54
  • yes the problem is in the command but i already changed the way ill do, now the only thing that blocks me is executing this command : git filter-branch --tree-filter 'rm -f $files' --prune-empty HEAD where $file="file1 file2..." it doesn't work but when i execute git filter-branch --tree-filter 'rm -f file1 file2...' --prune-empty HEADit works without any problem, why ? – Optimmus Jun 29 '16 at 11:35
  • Most likely because you are not exporting the `files` variable. The filtering command gets executed in a subshell, which has no knowledge of the parent shell's variables, unless they get exported. – Sam Varshavchik Jun 29 '16 at 11:55