67
. . Working with multiple git repositories Working with multiple git repositories Julien Pivotto T-Dose, Eindhoven October 26, 2014

Working with multiple git repositories

Embed Size (px)

DESCRIPTION

Talk I have given at T-Dose about git submodules and git slave and different worklow around them

Citation preview

Page 1: Working with multiple git repositories

...

Working with multiple git repositoriesWorking with multiple git repositories

Julien Pivotto

T-Dose, EindhovenOctober 26, 2014

Page 2: Working with multiple git repositories

..

whoamiwhoamiJulien PivottoJulien Pivotto

• System administrator at inuits.eu

• Git user for 5+ years• DevOps believer• Open-source defender since 2004• roidelapluie on twitter/github

Page 3: Working with multiple git repositories

..

Ops <3 DevOps <3 Dev

• Infrastructure as Code▶ SCM all the things▶ Monitoring▶ Configuration▶ Application deployment

• Taking part of software development▶ Understanding▶ Monitoring▶ High Availability▶ …

Page 4: Working with multiple git repositories

..

Me and gitMe and git

• I first used subversion (10 years ago)• Private forges and sourceforge• 5 years later a lot of projects moved to git• The Puppet community also uses a lot git• Git/Hg are the de-facto standards in OSprojects

Page 5: Working with multiple git repositories

..

Git is a free and open source distributed version control systemdesigned to handle everything from small to very large projects

with speed and efficiency.

Source: http://git-scm.com/

Page 6: Working with multiple git repositories

..

git loggit log

• Initiated in 2005 by Linus Torvalds• Replacement of closed-source BitKeeper• Created for the Linux Kernel development• Now used by thousands of projects

Page 7: Working with multiple git repositories

..

git is distributedgit is distributed

• Everything can be done in local (exeptpull&push)

• Work with several remotes• Share code with anyone• No unique central repository• A lot of workflows possible

Page 8: Working with multiple git repositories

..

Branching and merging is easyBranching and merging is easy

• You can branch locally• Merging is easy and simple• You can squash commits

Page 9: Working with multiple git repositories

..

How to access a repoHow to access a repo

• Locally (Local filesystems)• SSH• HTTP/HTTPs• Git protocol

Page 10: Working with multiple git repositories

..

git is open-sourcegit is open-source

• Published under GPL-2• Written in C• A lot of frontends/backends• A lot of libraries• A lot of hosting services• And a lot of users

Page 11: Working with multiple git repositories

..

Multiple git repos: why?Multiple git repos: why?

• Code isolation: plugins, libraries• Getting faster feedback from testing• Contributing back to upstream projects• Separate apps that are released together• Share code between projects

Page 12: Working with multiple git repositories

..

Multiple git repos usecasesMultiple git repos usecases

• Infrastructure as Code• Projects released together• Projects that embed external libraries• …

Page 13: Working with multiple git repositories

..

git submodules

Page 14: Working with multiple git repositories

..

git submodulesgit submodules

• Built-in with git• Embeds external repositories in asubdirectory or your repo

• Points these external repositories in aparticular commit

Page 15: Working with multiple git repositories

..

git submodulesgit submodules

• Submodules act like traditional gitrepositories

• Super repo contains a file with thesubmodules urls

• Super repo contains objects that can beupdated with commit hashes

Page 16: Working with multiple git repositories

..

Initiate super-repoInitiate super-repo.

.

$ git init .Initialized empty Git repository in /home/roidelapluie/super-repo/.git/$ > README$ git add README$ git commit -m "Initial commit"[master (root-commit) b526be8] Initial commit1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 README

Page 17: Working with multiple git repositories

..

Initiate subrepoInitiate subrepo.

.

$ git init .Initialized empty Git repository in /home/roidelapluie/subrepo/.git/$ > README$ git add README$ git commit -m "Initial commit"[master (root-commit) 41e64b6] Initial commit1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 README

Page 18: Working with multiple git repositories

..

Add first module in parent repoAdd first module in parent repo.

.

$ git submodule add ../subrepo/ subrepoCloning into 'subrepo'...done.$ git statusOn branch masterChanges to be committed:

(use "git reset HEAD <file>..." to unstage)

new file: .gitmodulesnew file: subrepo

Page 19: Working with multiple git repositories

..

What just happened?What just happened?

• git created a .gitmodules file• It cloned the subrepo in a directory• It created a git object that points to the repo• That object contains the git revision

Page 20: Working with multiple git repositories

..

.gitmodules file.gitmodules file

.

.

$ cat .gitmodules[submodule "subrepo"]

path = subrepourl = ../subrepo/

• Unique file for all the submodules• Only contains the path and the url• In this case, we use relative URL

Page 21: Working with multiple git repositories

..

Commiting our changeCommiting our change

.

.

$ git commit -m "Add subrepo"[master 3251a63] Add subrepo2 files changed, 4 insertions(+)create mode 100644 .gitmodulescreate mode 160000 subrepo

Page 22: Working with multiple git repositories

..

Cloning that super repoCloning that super repo

.

.

$ git clone /home/roidelapluie/super-repo/ .Cloning into '.'...done.$ ls subrepo/$ git submodule initSubmodule 'subrepo' (/home/roidelapluie/subrepo)registered for path 'subrepo'$ git submodule updateCloning into 'subrepo'...done.Submodule path 'subrepo': checked out '41e64b6bc0c970521c296b9c5e6a0b9144778962'

Page 23: Working with multiple git repositories

..

Shorcut #1Shorcut #1

.

.

$ git submodule init$ git submodule update

.

.

$ git submodule update --initSubmodule 'subrepo' (/home/roidelapluie/subrepo)registered for path 'subrepo'Cloning into 'subrepo'...done.Submodule path 'subrepo': checked out '41e64b6bc0c970521c296b9c5e6a0b9144778962'

Page 24: Working with multiple git repositories

..

Shorcut #2Shorcut #2.

.

$ git clone /home/roidelapluie/super-repo/ .$ git submodule init$ git submodule update

.

.

$ git clone --recurse-submodules /home/roidelapluie/super-repo/ .Cloning into '.'...done.Submodule 'subrepo' (/home/roidelapluie/subrepo)registered for path 'subrepo'Cloning into 'subrepo'...done.Submodule path 'subrepo': checked out '41e64b6bc0c970521c296b9c5e6a0b9144778962'

Page 25: Working with multiple git repositories

..

Working in a submoduleWorking in a submodule.

.

$ cd subrepo$ > newfile$ git add newfile$ git commit -m "add newfile"[detached HEAD 6ee0e71] add newfile1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 newfile

$ git pushfatal: You are not currently on a branch.To push the history leading to the current (detached HEAD)state now, use

git push origin HEAD:<name-of-remote-branch>

Page 26: Working with multiple git repositories

..

Checking out a branchChecking out a branch.

.

$ git checkout masterWarning: you are leaving 1 commit behind, not connectedto any of your branches:

6ee0e71 add newfile

If you want to keep them by creating a new branch, thismay be a good time to do so with:

git branch new_branch_name 6ee0e71

Switched to branch 'master'Your branch is up-to-date with 'origin/master'.

Page 27: Working with multiple git repositories

..

Merging our commitMerging our commit

.

.

$ git merge 6ee0e71Updating 41e64b6..6ee0e71Fast-forwardnewfile | 01 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 newfile

Page 28: Working with multiple git repositories

..

Pushing our commitPushing our commit

.

.

$ git pushCounting objects: 2, done.Delta compression using up to 8 threads.Compressing objects: 100% (2/2), done.Writing objects: 100% (2/2), 247 bytes | 0 bytes/s, done.Total 2 (delta 0), reused 0 (delta 0)To /home/roidelapluie/subrepo

41e64b6..6ee0e71 master -> master

Page 29: Working with multiple git repositories

..

Pushing our commitPushing our commit

.

.

$ date > newfile$ git commit -am "update newfile"[master 8a56806] update newfile1 file changed, 1 insertion(+)

$ git pushCounting objects: 3, done.Delta compression using up to 8 threads.Compressing objects: 100% (2/2), done.Writing objects: 100% (3/3), 310 bytes | 0 bytes/s, done.Total 3 (delta 0), reused 0 (delta 0)To /home/roidelapluie/subrepo

6ee0e71..8a56806 master -> master

Page 30: Working with multiple git repositories

..

Let's rewind..Let's rewind..

• A submodule not attached to a branch▶ Because submodules are referenced by their commit hashonly

▶ It is called the DETACHED HEAD

• How to push then?▶ The easy/safe option is to checkout a branch

• You only need to do that once

Page 31: Working with multiple git repositories

..

git submodule foreachgit submodule foreach

• git submodule foreach allow you to run acommand on each repo

▶ git submodule foreach git checkout master▶ git submodule foreach ls▶ git submodule foreach git commit -am "foo"

Page 32: Working with multiple git repositories

..

Meanwhile, on the super-project…Meanwhile, on the super-project….

.

$ git statusOn branch masterChanges not staged for commit:

(use "git add <file>..." to update what will becommitted)

(use "git checkout -- <file>..." to discard changes inworking directory)

modified: subrepo (new commits)

no changes added to commit (use "git add" and/or "gitcommit -a")

Page 33: Working with multiple git repositories

..

Update a subrepoUpdate a subrepo

.

.

$ git commit -am "update subrepo"[master 731626b] update subrepo1 file changed, 1 insertion(+), 1 deletion(-)

Page 34: Working with multiple git repositories

..

LogsLogs

.

.

$ git log -p --submodule=log subrepo/commit 731626bc53d8c248647443b4c0523d96d316cd24Author: Julien Pivotto <[email protected]>Date: Sat Oct 25 22:26:56 2014 +0200

update subrepo

Submodule subrepo 41e64b6..01c1b9c:> work on newfile> update newfile> add newfile

Page 35: Working with multiple git repositories

..

Change a submodules URLChange a submodules URL

• Edit .gitmodules and commit the file• Run git submodule sync• Now the submodule will use the new URL

Page 36: Working with multiple git repositories

..

git submodule --recursivegit submodule --recursive

• Run commands recursively• You can get multiple levels of submodules• But you add complexity

▶ Each level is 1 more commit you need to write▶ Playing with remote urls becomes tricky of you work withremotes

Page 37: Working with multiple git repositories

..

Submodules integrationSubmodules integration

• Integrated in git, standard• Integrated in CI tools (Jenkins)• Nothing specific needed for pulling• Need to checkout the submodules afterpulling

Page 38: Working with multiple git repositories

..

Submodules in GerritSubmodules in Gerrit

• Gerrit integrates submodules• It can create commits in "super-repo" if acode change is merged

• Not a perfect way of doing if changes in tworepo's are depending of each other

Page 39: Working with multiple git repositories

..

Submodules in GerritSubmodules in Gerrit

• Gerrit is integrated in CI tools• Gerrit allows fine tuning ACL• Gerrit code reviews with submoduleschanges don't display changes in thesubmodules

Page 40: Working with multiple git repositories

..

Submodules pros and consSubmodules pros and cons

− Each commit in submodule is not insuper-repo

− It is easy to rollback by accident asubmodule

− Getting logs is not easy− You can forget to update super-repo− Submodules are not attached to a branch

Page 41: Working with multiple git repositories

..

Submodules pros and consSubmodules pros and cons

+ Built-in+ Can use relative urls+ You can control the version of the

submodules+ Supported by many tools+ Easy rollbacks of submodules+ git bissect works (on the super repo)

Page 42: Working with multiple git repositories

..

gitslave a.k.a. gits

Page 43: Working with multiple git repositories

..

gitslavegitslave

• First public release in 2010• Wrapper around git• "gits" can be used in place of git• Run each git commands in each subrepos

Page 44: Working with multiple git repositories

..

Initiate gitsInitiate gits

.

.

$ git init .Initialized empty Git repository in /home/roidelapluie/superrepo/.git/$ gits prepare[master (root-commit) 594c492] gits creating .gitslave1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 .gitslave

Page 45: Working with multiple git repositories

..

Add a git repoAdd a git repo

.

.

$ gits attach /home/roidelapluie/subrepo/ subrepoCloning into 'subrepo'...done.[master 926321f] gits adding "/home/roidelapluie/subrepo/" "subrepo"2 files changed, 2 insertions(+)create mode 100644 .gitignore

$ cat .gitslave"/home/roidelapluie/subrepo/" "subrepo"

Page 46: Working with multiple git repositories

..

Cloning a repoCloning a repo

.

.

$ gits clone ../superrepo/ .Cloning into '.'...done.Cloning into 'subrepo'...done.

Page 47: Working with multiple git repositories

..

Working in submodulesWorking in submodules

.

.

$ cd subrepo$ date > newfile$ git add newfile$ gits commit -m "Work on newfile"On: subrepo:

[master 1230de3] Work on newfile1 file changed, 1 insertion(+), 1 deletion(-)

On: (super-repo):On branch masterYour branch is up-to-date with 'origin/master'.nothing to commit, working directory clean

Page 48: Working with multiple git repositories

..

Pushing changesPushing changes

.

.

$ gits pushOn: subrepo:

To /home/roidelapluie/subrepo/fbcf73c..1230de3 master -> master

On: (super-repo):Everything up-to-date

Page 49: Working with multiple git repositories

..

Pulling changesPulling changes

.

.

$ gits pullOn: (super-repo), subrepo:

Already up-to-date.

Page 50: Working with multiple git repositories

..

git slave workflowgit slave workflow

• Subrepos are always attached to a branch• You can work within them "normally"• Run almost any git command with "gits"

Page 51: Working with multiple git repositories

..

PerformancePerformance

• gits --parallel 8: run 8 parallel git commands• No extra commit in the super repository• Close to traditional git workflow

Page 52: Working with multiple git repositories

..

A branching approachA branching approach

• Use gits branch and gits checkout to switchbetween branches

• All the repositories will switch branches (e.g1.0, 1.1)

• Easy merge with gits merge• Avoid upstream traditional branch names

Page 53: Working with multiple git repositories

..

gits outputgits output

• gits will simplify the output of gitcommands

• It will group the repos by output• Easier to see the status, the remotes, etc

Page 54: Working with multiple git repositories

..

Pros and cons of gitslavePros and cons of gitslave

− Not integrated in tools− Requires an additional binary− Not integrated in git− Hard to rollback on every repositories

Page 55: Working with multiple git repositories

..

Pros and cons of gitslavePros and cons of gitslave

+ Close to git workflow+ Less error-prone+ Use traditional git commands+ Every git push arrives in the repo

Page 56: Working with multiple git repositories

..

Mitigeate gitslaves' issuesMitigeate gitslaves' issues

• Use git hooks to trigger tests on CI▶ Polling SCM does not scale anyway▶ Use the "Quite period" feature

• Use CI to add the same tag in eachrepository

▶ Rollback to a tag, not a commit▶ Add a tag at each commit

Page 57: Working with multiple git repositories

..

Additional tips

Page 58: Working with multiple git repositories

..

Use SSH socketsUse SSH sockets

.

.

$ cat .ssh/configHost githost

controlmaster autocontrolpath /tmp/ssh-%r@%h:%pControlPersist 300

• Use only one SSH connection• Do not disconnect SSH

Page 59: Working with multiple git repositories

..

Find the tag of a commitFind the tag of a commit

.

.

$ git name-rev --name-only 106cb38dd0bc5ea2d2d0adef0b4006bd61884e42remotes/origin/8.5.2~1

Page 60: Working with multiple git repositories

..

git autocorrectgit autocorrect

.

.

$ git config help.autocorrect 10$ git puskWARNING: You called a Git command named 'pusk', which does not exist.Continuing under the assumption that you meant 'push'in 1.0 seconds automatically...

Page 61: Working with multiple git repositories

..

Use git hooksUse git hooks

• Multiple repositories = a lot of pull• Jenkins pulling X repos X times every 5minutes is a bad idea

• Git hooks to the resue• Reduce load on Jenkins and the git server• Reduce the time before Jenkins launchesbuilds

Page 62: Working with multiple git repositories

..

GPG-Sign your commitsGPG-Sign your commits

• git commit -S• Sign PR, merge commits• Do not sign every commit (then it becomesuseless)

Page 63: Working with multiple git repositories

..

Keeping multiple remotes in syncKeeping multiple remotes in sync

• git remote set-url --add• Pull & push will ose both urls

Page 64: Working with multiple git repositories

..

HomeworkHomework

• Git subtree (also built-in)• Repo (from Android)• gr• …

Page 65: Working with multiple git repositories

..

ConclusionsConclusions

• Git is an awesome, extandable tool• There are several ways to manage multiplegit repositories

• Working with multiple repos is easy• You have to learn tools anyway• Experiment them and pick one :-)

Page 66: Working with multiple git repositories

..

Thank youThank you

Any question?

Page 67: Working with multiple git repositories

..

ContactContact

Julien [email protected]@roidelapluie

INUITS bvbaBelgium+32 473 441 636https://inuits.eu