
Git is a distributed version control system originally developed in 2005 by Linus Torvalds, the creator of the Linux operating system. Git commands are used to maintain a repository of git projects, where each project tracks changes to a set of files.
A fairly common activity for developers is to transfer a git project from one repository to another one. There are several ways to do this. However, the environments I typically work in have rather severe security constraints, so I’m not expecting one repository to have direct access to the other repository.
A Whirlwind Tour of Git
Git maintains a tree structure of file changes over time, which can be thought of as the history of changes to the files. The “trunk” of the tree is referred to as “master.” Branches represent a named fork, or set of changes, that have diverged from master. Branches can be merged into other branches. In fact, master is nothing more than a branch, so branches can be merged into master.
Over time, the usual goal of software development teams is to collect all of the tested and working changes to software files on the master branch. Other branches remain in the project, but are generally never used again. In a sense, the repository becomes littered with the detritus of hundreds or more discarded branches.
What to Move
When moving a git repository, it’s important to define what will be moved. There are three possibilities:
- Just the current source files
- The master branch and its history of changes
- All branches and the history of changes to all branches
History is important, because it allows one to see who made changes to the code, what they changed, and, if the developers were sufficiently disciplined, a description of why they made changes. History is vital for the changes to the master branch…but not so much for other branches. Either the changes were discarded, in which case we don’t really care about them, or they were merged into master when a feature was completed, in which case the changes are already present in master.
The bottom line is that option #1 is a non-starter, # 2 is my recommended approach, and #3 perpetuates a bloated project. It’s also possible to choose option #2, but add a defined set of other branches if necessary.
Transfer Process
In order to transfer a git project, we’ll export it from the source git repository and import it into the destination git repository.
STEP 1: Exporting a Git Project
1. Clone the git project into a local directory.
git clone <repository URL>
This will create sub-directory in your current directory with the name of the repository you cloned. It also automatically links your new local repository back to the original source (the “remote”), so you can easily sync changes later.
2. Go into the repository directory.
cd <repository name>
3. The clone action automatically brought in the master branch. If any other branches are needed, add them as follows:
git checkout <branch name>
4. Fetch all of the tags from the git project.
git fetch --tags
Tags are basically alphanumeric labels that designate a certain “place” on the trunk, e.g. – “ver1_1” for version 1.1 of a software release.
5. Remove the link to the origin git project.
git remote rm origin
To verify that the origin setting has been removed:
git remote –v show
6. Go back up to the directory that contains your cloned git repository.
cd ..
7. Zip up the git project.
zip –r
By convention, provide a descriptive name for the zipfile, such as “zork_game_source_code.” There is no need to specify a “.zip” extension; that will be done automatically.
STEP 2: Importing a Git Project
We’ve moved to new server, designated as the Staging Server, with no direct network access to the original server. This the destination to which we’ll be importing the repository we zipped up in Step 1.
1. Create a new git repository, sometimes referred to as a “git project.”
To accomplish this, go to the admin interface (for GitLab, GitHub, or some other UI) or command-line (for barebones git instances) for managing git repositories. Create a new git project. Record the URL of the newly created repository for later use (this will be designated as the new “origin URL” in later steps). To avoid any potential conflicts, do not initialize the project with any files.
2. Upload the provided zipfile (containing a git project to be transitioned) to the designated Staging Server.
3. From the command-line of the Staging Server, unzip the provided zipfile.
unzip <zip file>
4. Go to the newly created staging directory containing the contents of the zipfile.
cd <repository name>
5. Add a link to the new remote origin.
git remote add origin <new repository URL>
6. Push the source files to the new remote origin.
git push origin --all
7. Push the tags to the new remote origin.
git push origin --tags
The software project has now been transferred to the new git repository. This includes the master branch, with its history of changes, and any related tags.
This was accurate when the post was written. However, now when you do a
git cloneoperation, it brings down the entire repository, including all branches and tags. In Step 1, this means you can eliminate #3 and #4. In Step 2, you’ll have to check, but #7 may no longer be needed.Basically, the defaults for git changed, and for the better, I think.