Git Subtree
Originally posted at 1/10/2011
I have no idea why, but yesterday I tried using the git-subtree project on a different machine, and it did not work. Today, I tried it on my main work machine, and It Just Worked.
At any rate, let us see where we are, shall we?
PS C:\Work\temp> git init R1 Initialized empty Git repository in C:/Work/temp/R1/.git/ PS C:\Work\temp> git init R2 Initialized empty Git repository in C:/Work/temp/R2/.git/ PS C:\Work\temp> git init Lic Initialized empty Git repository in C:/Work/temp/Lic/.git/ PS C:\Work\temp> cd R1 PS C:\Work\temp\R1> echo "Hello Dolly" > Dolly.txt PS C:\Work\temp\R1> git add --all PS C:\Work\temp\R1> git commit -m "initial commit" [master (root-commit) b507184] initial commit 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Dolly.txt PS C:\Work\temp\R1> cd ..\R2 PS C:\Work\temp\R2> echo "Hello Jane" > Jane.txt PS C:\Work\temp\R2> git add --all PS C:\Work\temp\R2> git commit -m "initial commit" [master (root-commit) ec99676] initial commit 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Jane.txt PS C:\Work\temp\R2> cd ..\Lic PS C:\Work\temp\Lic> echo "Copyright Ayende (C) 2011" > license.txt PS C:\Work\temp\Lic> git add --all PS C:\Work\temp\Lic> git commit -m "initial commit" [master (root-commit) a3a9b48] initial commit 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 license.txt PS C:\Work\temp\Lic> cd.. PS C:\Work\temp> git clone .\Lic Lic.Bare --bare Cloning into bare repository Lic.Bare... done.
Those are the current repositories, and we want to be able to share the Lic repository among the two projects. Note that we created a bare repository for Lic, because we can’t by default push to a remote repository if it is not bare.
Using git subtree, we can run:
PS C:\Work\temp> cd .\R1
PS C:\Work\temp\R1> git subtree add --prefix Legal C:\Work\temp\Lic.Bare master
git fetch C:\Work\temp\Lic.Bare master
warning: no common commits
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From C:\Work\temp\Lic.Bare
* branch master -> FETCH_HEAD
Added dir 'Legal'
PS C:\Work\temp\R1> ls -recurse
Directory: C:\Work\temp\R1
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 1/10/2011 11:59 AM Legal
-a--- 1/10/2011 11:58 AM 28 Dolly.txt
Directory: C:\Work\temp\R1\Legal
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 1/10/2011 11:59 AM 56 license.txt
We do the same in the R2 repository:
PS C:\Work\temp\R1> cd ..\R2 PS C:\Work\temp\R2> git subtree add --prefix Legal C:\Work\temp\Lic.Bare master git fetch C:\Work\temp\Lic.Bare master warning: no common commits remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From C:\Work\temp\Lic.Bare * branch master -> FETCH_HEAD Added dir 'Legal'
Now let us see what happen when we modify things…
PS C:\Work\temp\R2> echo "Not for Jihad use" > .\Legal\disclaimer.txt PS C:\Work\temp\R2> git add --all PS C:\Work\temp\R2> git commit -m "adding disclaimer" [master 3ac3e15] adding disclaimer 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Legal/disclaimer.txt
Couple of things to note here:
- We could add & commit from the root repository, because as far as Git is concerned, there is only one repository.
- If we were to push our changes to the root repository location, it would include the changes just made.
This is a Good Thing, because if I want to create a branch / fork, I get everything, not just references.
Now, let us push our changes to the Lic repository:
PS C:\Work\temp\R2> git subtree push C:\Work\temp\Lic.Bare master --prefix Legal git push using: C:\Work\temp\Lic.Bare master 1/ 4 (0)2/ 4 (0)3/ 4 (0)4/ 4 (1)Counting objects: 4, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 320 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To C:\Work\temp\Lic.Bare a3a9b48..10fea68 10fea680b0783e0cf6e5d3ba5130d154557ffbe5 -> master
And now let us see how we get those changes back in the R1 repository:
PS C:\Work\temp\R1> git subtree pull C:\Work\temp\Lic.Bare master --prefix Legal remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From C:\Work\temp\Lic.Bare * branch master -> FETCH_HEAD Merge made by recursive. Legal/disclaimer.txt | Bin 0 -> 40 bytes 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Legal/disclaimer.txt PS C:\Work\temp\R1> ls -recurse Directory: C:\Work\temp\R1 Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 1/10/2011 12:04 PM Legal -a--- 1/10/2011 11:58 AM 28 Dolly.txt Directory: C:\Work\temp\R1\Legal Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 1/10/2011 12:04 PM 40 disclaimer.txt -a--- 1/10/2011 11:59 AM 56 license.txt
There is another important advantage for git subtree, it is only me that have to use this, everyone else can just work with the usual git tools, and not have to be aware that I am sharing code between projects in this manner.
Comments
this
is
cool
I was so used to the submodule way of doing things (i.e. cannot really change things from the root of the 'host' repository), that I never even explored subtree.
how did you manage to make subtree work outside of bash?
Ken,
It just worked, I have no idea how.
I just copied the files to the git-core dir, and it did.
And now you get why I find submodule so unfitting?
You never know how bad your situation really is until you experience a better one
I wish I could use subtree. I've been looking at it for quite a while. What's stopping me is that they are not officially supported. Git slave is something else to consider.
are there any issues with:
team city
Branch management: merging, rebasing and hence conflicts
Tagging
So for an organization, how does the "in anger" use look like?
Adam
Comment preview