I have been developing a new client software for xrootd using GitHub for quite a long while. At some point, it has been decided that the new client code will be merged into the xrootd code base. Everything in the XrdCl directory in the github repo was to be moved to src/XrdCl in the main repo, and everyting in XrdClTests to tests/XrdClTests. Ohh, and all the commit history had to be preserved.

As it turns out, all this is not much of a big deal for git-subtree :)

  1. Having fresh checkouts of both repositories is a good idea.

    ]==> git clone git@github.com:ljanyst/xrdclient.git
    ]==> git clone iris02.slac.stanford.edu:/blah/blah/xrootd.git
    
  2. Since we need to move contents of two directories separately, we create detached branches containing contents of each directory in the root and annotate the commit messages accordingly.

    ]==> cd xrdclient
    
    ]==> git subtree split --prefix=XrdClTests --annotate="[XrdClTests] " -b XrdClTests
    Created branch 'XrdClTests'
    d893dbd61628da614d1aa504ab355310e4c621a3
    
    ]==> git subtree split --prefix=XrdCl --annotate="[XrdCl] " -b XrdCl
    Created branch 'XrdCl'
    d04ed95318d9055482eebc815a49d08a046a1a0c
    
  3. We add the subtrees in the branches of the source repository to the target repository.

    ]==> cd ../xrootd
    
    ]==> git subtree add --prefix=tests/XrdClTests ../xrdclient XrdClTests
    git fetch ../xrdclient XrdClTests
    warning: no common commits
    remote: Counting objects: 444, done.
    remote: Compressing objects: 100% (143/143), done.
    remote: Total 444 (delta 308), reused 322 (delta 301)
    Receiving objects: 100% (444/444), 91.36 KiB, done.
    Resolving deltas: 100% (308/308), done.
    From ../xrdclient
    * branch XrdClTests -> FETCH_HEAD
    Added dir 'tests/XrdClTests'
    
    ]==> git subtree add --prefix=src/XrdCl ../xrdclient XrdCl
    git fetch ../xrdclient XrdCl
    remote: Counting objects: 1520, done.
    remote: Compressing objects: 100% (317/317), done.
    remote: Total 1520 (delta 1204), reused 1247 (delta 1203)
    Receiving objects: 100% (1520/1520), 419.10 KiB, done.
    Resolving deltas: 100% (1204/1204), done.
    From ../xrdclient
    * branch XrdCl -> FETCH_HEAD
    Added dir 'src/XrdCl'
    

The man page of git-subtree says that: "Repeated splits of exactly the same history are guaranteed to be identical (ie. to produce the same commit ids). Because of this, if you add new commits and then re-split, the new commits will be attached as commits on top of the history you generated last time, so 'git merge' and friends will work as expected."

This works for git subtree pull as well, so, after adding new commits to the source and splitting, the new stuff can be cleanly merged to the target repo.

]==> git subtree pull --prefix=tests/XrdClTests ../xrdclient XrdClTests
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From ../xrdclient
* branch XrdClTests -> FETCH_HEAD
Merge made by the 'recursive' strategy.
tests/XrdClTests/FileSystemTest.cc | 66 ++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)

]==> git subtree pull --prefix=src/XrdCl ../xrdclient XrdCl
remote: Counting objects: 35, done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 27 (delta 20), reused 0 (delta 0)
Unpacking objects: 100% (27/27), done.
From ../xrdclient
* branch XrdCl -> FETCH_HEAD
Merge made by the 'recursive' strategy.
src/XrdCl/CMakeLists.txt | 3 ++
src/XrdCl/XrdClDefaultEnv.cc | 31 ++++++++++++
src/XrdCl/XrdClFile.hh | 18 ++++++-
src/XrdCl/XrdClFileSystem.cc | 93 ++++++++++++++++++++++++++++++++++++
src/XrdCl/XrdClFileSystem.hh | 81 +++++++++++++++++++++++++++++++
src/XrdCl/XrdClXRootDMsgHandler.cc | 2 +
src/XrdCl/XrdClXRootDTransport.cc | 77 ++++++++++++++++++++++++-----
7 files changed, 292 insertions(+), 13 deletions(-)
If you like this kind of content, you can subscribe to my newsletter, follow me on Twitter, or subscribe to my RSS channel.