9

I am very much familiar with git cherry-pick. Currently i am trying to cherry-pick few commits from other git repository. Scenario is as below:

A -> git repo ("A/foo/B" where B is a directory inside foo)

B -> git repo

My intention is to cherry-pick/apply-patches/merge commits of git repo B to A/foo/B directory.

A/foo/B

I know it can be done in many ways, like with merge, cherry-pick and applying patch.

I have also tried below command, which is fulfilling my intention:

git --git-dir=../B/.git format-patch --stdout sha1^..sha1 | git am --directory='B/'

But is there any way to get the same thing with cherry-pick to get the intended solution Or any other perfect solution to make it up.

Please suggest!!

Thank you :)

love
  • 1,000
  • 2
  • 16
  • 35
  • What about submodule? – CodeWizard Oct 07 '15 at 06:50
  • Moving a directory and cherry picking a commit only have something in common if the commit you are picking moved the directory. Generally speaking, you should probably avoid doing a large number of cherry picks, and if you would require this, you might want to think of an alternative. – Tim Biegeleisen Oct 07 '15 at 06:51
  • 1
    @codeWizard I have tried using submodules following link https://groups.google.com/forum/#!topic/git-users/HXoX-kpkYkM but the problem is i am unable to retain file level history in that. I want want to retain file level history as well. – love Oct 07 '15 at 06:55
  • Its not a problem, you can do it like in any other repo. if you want to filter data (get rid of other folders) you can use `filter-branch` for example to remove all the unwanted content. Submodule is simply a git repo inside other git repo – CodeWizard Oct 07 '15 at 06:56
  • @codeWizard any example would be a great help :) or you may update the answer with an example. – love Oct 07 '15 at 06:57
  • Working on example right now. few minutes – CodeWizard Oct 07 '15 at 07:00
  • @codeWizard Ok..thanks a lot :) – love Oct 07 '15 at 07:02
  • Added a sample code - feel free to ping me on any question or request to any other issues if i misunderstood you. – CodeWizard Oct 07 '15 at 07:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/91563/discussion-between-love-and-codewizard). – love Oct 07 '15 at 07:44

2 Answers2

2

You can either use checkout-index or just checkout. Both have pros and cons.

With checkout-index

  1. Change your working dir to repo A
  2. git --git-dir=../B/.git checkout-index -a --prefix=B/
  3. git add B
  4. git commit

checkout-index checks out (as the name implies) the index of a repository. Thus you must ensure that the index of repo B looks like you want it. The pro is that you can modify the index before you check it out to your working directory.

With checkout

  1. Change your working dir to repo A
  2. mkdir B
  3. git --git-dir=../B/.git --work-tree=B checkout HEAD -- .
  4. git add B
  5. git commit

The pro of checkout is that you can pick any commit as it is. Use a branch, commit id or tag instead of HEAD.

The con is that if you checkout any other commit than HEAD the HEAD and index of repository B will change. So if you go back to the repository B you will see this changes if you do a git status.

what if i already have a directory name B in it and i just want to cherry-pick few commits from repository B to B directory

With checkout-index files that already exist in folder B will not be overwritten until you specify --force or just -f.

The checkoutcommand above will overwrite files that already exist, because I use -- . at the end. You can select specific files by replacing . with the path. E.g. if you only want to checkout a src directory.

git --git-dir=../B/.git --work-tree=B checkout HEAD -- src
René Link
  • 48,224
  • 13
  • 108
  • 140
  • 1
    Thanks Rene for your answer, what if i already have a directory name B in it and i just want to cherry-pick few commits from repository B to B directory. Sorry for the trouble, i have modified the question a bit. – love Oct 07 '15 at 07:47
0

You can use submodules.

Submodules/subtree are basically git repository inside another git repository.

The main difference between subtree and submodule is where your files are managed (as standalone repository or in the parent repository).

Here is a simple script which creates 2 repositories and then add one of them as submodule of the second repository.

At this point and changes which are made inside the submodule folder are "transparent" to the parent repo (repo1)


# Clear old repositories if any
rm -rf /tmp/repo1
rm -rf /tmp/repo2

# Creating new empty repositories
git init repo1
git init repo2

# commiting to the first repository
cd /tmp/repo1
echo 'a' > file1.txt
git add .
git commit -m "Commiting to repo1"

# commiting to the second repository
cd /tmp/repo2
echo 'b' > file2.txt
git add .
git commit -m "Commiting to repo2"

# Adding repo2 as submodule of repo1
cd /tmp/repo1
git submodule add /tmp/repo2 repo2
git submodule init
git submodule update
CodeWizard
  • 128,036
  • 21
  • 144
  • 167