Skip to content
David Sanderson edited this page Aug 29, 2023 · 7 revisions

This will guide you through a simple example of how to use git-subrepo.

Start with installing git subrepo and make sure that you can run

$ git subrepo
usage: git subrepo <command> <arguments> <options>

Let us start with creating a new repository in the shared directory where we have our common files bar and foo.

$ cd /tmp/shared
$ git init
Initialized empty Git repository in /tmp/shared/.git/
$ git add .
$ git commit -m "Initial revision of our shared code"
[master (root-commit) 1c1c881] Initial revision of our shared code
 2 files changed, 2 insertions(+)
 create mode 100644 bar
 create mode 100644 foo

Then we clone our project repository, contains one file called alpha.

$ cd /tmp/
$ git clone project_bare project
Cloning into 'project'...
done.

To use the shared repository as a subrepo inside the project.

$ cd /tmp/project
$ git subrepo clone /tmp/shared
Subrepo '/tmp/shared' (master) cloned into 'shared'.
$ git ls-files
alpha
shared/.gitrepo
shared/bar
shared/foo
$ git log --oneline
cadfff1 (HEAD -> master) git subrepo clone /tmp/shared
68442e4 (origin/master) New alpha

As you can see shared has been a part of the project repository, the only thing that tells us that there is a subrepo is the .gitrepo file. This file is used to store some subrepo essential information.

$ cat shared/.gitrepo 
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/ingydotnet/git-subrepo#readme
;
[subrepo]
        remote = /tmp/shared
        branch = master
        commit = 1c1c881f2232f5f80e6c67a4d31d28ed1f1d90cf
        parent = 68442e465e2ea3e9ece0718234556f1b82628d79
        method = merge
        cmdver = 0.4.0

Now you can start to work on your project.

$ touch delta
$ echo 123 >> shared/foo 
$ git add .
$ git commit -m "Add delta, edit shared/foo"
[master d8b0e12] Add delta, edit shared/foo
 2 files changed, 1 insertion(+)
 create mode 100644 delta
$ echo abc >> alpha 
$ git add .
$ git commit -m "Edit alpha"
[master 3b068bd] Edit alpha
 1 file changed, 1 insertion(+)
$ touch shared/fie
$ git add .
$ git commit -m "Add shared/fie"
[master ed859fe] Add shared/fie
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 shared/fie
$ git log --oneline
ed859fe (HEAD -> master) Add shared/fie
3b068bd Edit alpha
d8b0e12 Add delta, edit shared/foo
cadfff1 git subrepo clone /tmp/shared
68442e4 (origin/master) New alpha

Some changes and new files. So far we have only worked in our local repository. To share our changes to others we perform a regular push.

$ git push
Counting objects: 17, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (17/17), 1.66 KiB | 0 bytes/s, done.
Total 17 (delta 3), reused 0 (delta 0)
To /tmp/project_bare
   68442e4..ed859fe  master -> master

Now the changes are available to everyone working on the project repository. But if we look at our shared subrepo we will see that nothing has happened there.

$ cd /tmp/shared
$ git log --oneline
1c1c881 (HEAD -> master) Initial revision of our shared code

Why? Because the subrepo will not update unless we specifically tell it to. Lets say that we add another file in the subrepo.

$ touch idle
$ git add .
$ git commit -m "Add idle"
[master 6702317] Add idle
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 idle
$ echo 123545 >> bar 
$ git add .
$ git commit -m "Edit bar"
[master 2cb9f79] Edit bar
 1 file changed, 1 insertion(+)
$ git log --oneline
2cb9f79 (HEAD -> master) Edit bar
6702317 Add idle
1c1c881 Initial revision of our shared code
$ git checkout -b other       # We need to step away from master if we want others to push changes here
Switched to a new branch 'other'

If we want to use this in our project, we need to update the subrepo.

$ cd /tmp/project
$ git subrepo pull shared
Subrepo 'shared' pulled from '/tmp/shared' (master).
$ git log --oneline
d2bbc1e (HEAD -> master) git subrepo pull (merge) shared
ed859fe (origin/master) Add shared/fie
3b068bd Edit alpha
d8b0e12 Add delta, edit shared/foo
cadfff1 git subrepo clone /tmp/shared
68442e4 New alpha
$ git ls-files
alpha
delta
shared/.gitrepo
shared/bar
shared/fie
shared/foo
shared/idle

But wait, we have changes in our project repository that we want to get back into shared subrepo. As with regular git, you use push for this.

$ cd /tmp/project
$ git subrepo push shared
Subrepo 'shared' pushed to '/tmp/shared' (master).
$ cd /tmp/shared
$ git checkout master     # We need to get back to master to see the changes we pushed
Switched to branch 'master'
$ git log --oneline --graph
*   c6b4908 (HEAD -> master) git subrepo pull (merge) shared
|\  
| * 2cb9f79 (other) Edit bar
| * 6702317 Add idle
* | 2ecfb0b Add shared/fie
* | 8ab2ea9 Add delta, edit shared/foo
|/  
* 1c1c881 Initial revision of our shared code

Now lets compare the project and shared to see what has actually happened here. We start with a diff.

$ diff /tmp/project/shared/ /tmp/shared/
Only in /tmp/shared/: .git
Only in /tmp/project/shared/: .gitrepo

It tells us that .git is only available in the shared, it will not be present in the project. The .gitrepo file is only present in the /tmp/project/shared/, as it stores data specific for the project usage of shared.

If we use log and compare shared and project

$ cd /tmp/shared
$ git log --oneline --graph
*   c6b4908 (HEAD -> master) git subrepo pull (merge) shared   # 
|\  
| * 2cb9f79 (other) Edit bar              # Subrepo change
| * 6702317 Add idle                      # Subrepo change
* | 2ecfb0b Add shared/fie                # Subrepo version of ed859fe
* | 8ab2ea9 Add delta, edit shared/foo    # Subrepo version of d8b0e12
|/  
* 1c1c881 Initial revision of our shared code 
$ cd /tmp/project
$ git log --oneline --graph
* 15b09d7 (HEAD -> master) git subrepo push shared  # Update .gitrepo file
* d2bbc1e git subrepo pull (merge) shared # Merge local change with 2cb9f79 and 6702317 from subrepo
* ed859fe (origin/master) Add shared/fie  # Only change subrepo, visible in subrepo
* 3b068bd Edit alpha                      # Only changed project, not visible in subrepo    
* d8b0e12 Add delta, edit shared/foo      # Change both project and subrepo, visible in subrepo
* cadfff1 git subrepo clone /tmp/shared   # Clone in state from 1c1c881
* 68442e4 New alpha                       # Start repo
Clone this wiki locally