tags:

views:

73

answers:

2

I have a project "A" that is a Git repository. I would like to be able to make multiple copies of project A (B and C), and modify them for clients.

"A" is the master so sometimes when I do new functionality i would like to be able to pull them into B or C. But some commits should just stay in A and only be used if making a new clone.

How do I do that with Git? That is:

  • how to copy A? (Clone?)
  • how to get specific commits into B and C?

Please keep in mind that this all happening locally - not on GitHub. I use OS X.

+1  A: 
  • how to copy A?

git clone is the way, meaning you establish a publication link between A and B,C, allowing for pushing/pulling commits between them.

  • how to get specific commits into B and C?

By having in the repo A:

  • private branches where you develop as many feature you want (but this branch is never pushed anywhere else)
  • public branch which will be pushed to B and C
  • merge or rebase --onto your commits from your private branch on top of your public branch, then push that public branch to B or C.

One workflow would be for instance:

cd ~/projectA
git checkout master
git branch private
# do some commits, some private, some useful to a
git checkout master
git branch feature_for_a
git cherry-pick sha1_from_private

cd ~/project_B
git fetch project_A
git checkout --track feature_for_a # check modifs for a
git checkout master
git merge feature_for_a
# do some client specific modifications
VonC
Thanks a lot for your reply. Can you write the commands for a typical workflow? Eg. 1. git clone ~/project_a ~/project_b 2. [make changes to project_a] 3. [now what? :)]
jriff
@jriff: answer updated with *one example* of possible workflow
VonC
BTW. Some commits should only go to some of the clones. A commit might be a feature or a bugfix that doesn't need to go to all the clones. Also I think it would be better to pull the commits I want rather than push them from project_a.
jriff
@jriff: the cherry-pick step is meant precisely to pick and choose what commit you want in branches meant for other repo. And since you fetch them (and create a local branch in b for tracking what you have fetch, that is similar to pull them), you are not pushing anything from project_a: you can't, project_b being a non-bare repo, it is not eligible to any direct push from project_a
VonC
Thanks a lot - could you have a look at the answer I made - it is similar to your workflow - only a little simpler - can you explain the drawbacks of that approach?
jriff
@jriff: I believe I just did ;)
VonC
Our comments crossed each other :^)
jriff
A: 

What about this approach:

mkdir project_a
[make entire project]
git add .
git commit -a -m "Initial commit"

git clone project_a project_b

[make bugfix in project_a]
git commit -a -m "VERY important Bugfix"
[make insignificant change]
git commit -a -m "change that doesn't matter to anyone in the world"

Now I want to get the very important bugfix:

In the dir. of project_b
git fetch
git cherrypick -x [SHA of the very important bugfix]

Are there any drawbacks to this? As I see it I can pick the commits I want. But what if I do a git pull in project_b by mistake? Won't that give me a ton of problems?

jriff
It's another way, by I prefer preparing a clean history in project_a, and then fetching that history (isolated on a special branch) to project_b in order to have only to focus on integrating (merging) this to project_b current development.
VonC
Could you elaborate on the "clean history" part? I don't think I quite get the advantage.
jriff
@jriff: the idea is to isolate the commit you want to publish to other repos from the original repo, where you can reorder in a special branch. Then, from project_b, all you do is fetching that branch and merge it. You do not have to pick anything. This is important, because the context where "fixes for project_b" and "fixes only for project_a" makes sense in within the project_a. This is from project_a that you realize that everything is not for project_b. Hence the idea to sort them in project_a, isolating relevant commits for project_b in a special branch you can then fetch from b.
VonC
I have been thinking about your suggestion above - I think I see the point. But what about the branch in project_a? When it has been fetched - do I delete it in project_a?
jriff