Reality is not always satisfactory. In general, you can't switch to Git for every item you touch immediately. Sometimes you get stuck in a project that uses other VCS, but you want to use Git. In the first part of this chapter we will learn how to use Git clients on your projects that are hosted on different systems.
At some point, you might want to convert an existing project to Git. The second part of this chapter covers ways to migrate your project from several specific systems to Git, even without pre-built import tools, and we have a way to manually import them. Git as a client
GIT provides developers with such a great experience, and many people have found ways to use Git on their workstations, even if the rest of their team is using a completely different VCS. There are many of these available adapters, which are called "bridging". Below we will introduce several bridges that are likely to be used in practice. Git and Subversion
A large part of the open source project uses Subversion to manage their source code with quite a few enterprise projects. And for most of the time, it's already the de facto standard of VCs selection for open source projects. It is similar in many ways to CVS, a big shot in the world of source code management.
One of the best features of Git is a two-way bridge with Subversion, which is called Git svn. This tool allows you to use Git as a client to connect to subversion, so you can use all the local features of Git and push it to the Subversion server as if you were using subversion locally. This means that you can create new branches and merge branches locally, use staging area, use variable base and picking, and so on, while collaborators continue to use their dark and old ways. When you try to persuade the company to modify the infrastructure to fully support git, a good way is to sneak git into the corporate environment and help the developers around them improve their efficiency. Subversion Bridge is the bait to enter the DVCS world. git svn
The basic command for all Subversion bridge commands in Git is git svn. It can follow a lot of commands, so we'll show you the most commonly used commands through a few simple workflows.
It is important to note that when you use Git svn, you are dealing with Subversion, a system that is completely different from git. Although you can create new branches and merge branches locally, it's best to make sure your history is as straight-line as possible by changing your work, and avoid doing things like interacting with Git remote servers at the same time.
Don't rewrite your history and try pushing again, and don't push to a parallel git repository to work with other git developers. Subversion can only have a linear history, it is easy to mess it up. If you work in a team, some of them use SVN and others use Git, you need to make sure everyone uses the SVN server to collaborate-it saves a lot of hassle. Set
To demonstrate this functionality, a typical SVN repository with write access is required. If you want to copy these examples, you must obtain a writable copy of my test repository. For easy copying, you can use a tool called Svnsync, which comes with Subversion. For these tests, we created a new Subversion repository with a partial copy of the PROTOBUF project on Google Code. Protobuf is a tool that encodes structural data for network transmission.
Next, you'll need to create a new local Subversion repository:
$ mkdir/tmp/test-svn
$ svnadmin create/tmp/test-svn
Then, allow all users to change version properties-The easiest way is to add a Pre-revprop-change script that returns a value of 0.
$ cat/tmp/test-svn/hooks/pre-revprop-change
#!/bin/sh
exit 0;
$ chmod +x/tmp/test-svn/hooks/pre-revprop-change
You can now invoke the Svnsync init command that joins the target with the source warehouse parameter to synchronize this project to the local machine.
$ svnsync init file:///tmp/test-svn \
http://progit-example.googlecode.com/svn/
This sets up the properties used by the synchronization. You can clone the code by running the following command:
$ svnsync Sync file:///tmp/test-svn
Committed Revision 1.
Copied Properties for Revision 1.
Transmitting file data ......... ............. [...]
Committed Revision 2.
Copied Properties for revision 2.
[...]
While this may only take a few minutes, if you try to copy the original warehouse to another non-local remote repository, the process can take nearly one hours, even if there are fewer than 100 commits. Subversion must replicate one version at a time and then push it back to the other warehouse-it's ridiculously inefficient, but it's the only easy way to do it. Start
Now that you have a Subversion repository with Write permissions, you can start a typical workflow. You can start with the git svn clone command, which imports the entire Subversion repository into a local git repository. One thing to keep in mind is that if you are importing from a truly managed Subversion repository, you need to replace file:///tmp/test-svn with the URL of your Subversion repository:
$ git svn clone File:///tmp/test-svn-T trunk-b branches-t tags Initialized empty git repository in/private/tmp/pr
OGIT/TEST-SVN/.GIT/R1 = dcbfb5891860124cc2e8cc616cded42624897125 (refs/remotes/origin/trunk) A m4/acx_pthread.m4 A m4/stl_hash.m4 a Java/src/test/java/com/google/protobuf/unknownfieldsettest.java a java/src/test/java/com/google /protobuf/wireformattest.java R75 = 556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae (refs/remotes/origin/trunk) Found Possible branch point:file:///tmp/test-svn/trunk = file:///tmp/test-svn/branches/my-calc-branch, a Found branch Parent: (Refs/remotes/origin/my-calc-branch) 556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae following parent with Do_ Switch successfully followed parent R76 = 0FB585761DF569EAECD8146C71E58D70147460A2 (refs/remotes/origin/ My-calc-branch) Checked out Head:file:///tmp/test-svn/trunk R75
This is equivalent to running two commands-git svn init and then git svn fetch-the URL you provided. It will take some time. The test project has only about 75 commits and the codebase is not very large, but Git has to check out a version one at a time and commit it separately. For projects with hundreds or thousands of commits, this can really take hours or even days to complete.
The-T trunk-b branches-t tags section tells the Git Subversion repository to follow the basic branching and tagging conventions. If you name a different trunk, branch, or tag, you can modify these parameters. Because this is so common, you can use-s instead of the whole part, which represents the standard layout and refers to all those options. The following commands are the same:
$ git svn clone file:///tmp/test-svn-s
At this point, you should get a valid Git repository with branches and tags already imported:
$ git branch-a
* Master
remotes/origin/my-calc-branch
remotes/origin/tags/2.0.2
remotes/origin/ tags/release-2.0.1
remotes/origin/tags/release-2.0.2
remotes/origin/tags/release-2.0.2rc1
remotes/ Origin/trunk
Note how this tool manages Subversion tags as remote references. Let's take a closer look at Git's bottom command show-ref:
$ git show-ref
556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae refs/heads/master
0FB585761DF569EAECD8146C71E58D70147460A2 Refs/remotes/origin/my-calc-branch
bfd2d79303166789fc73af4046651a4b35c12f0b refs/remotes/origin/tags/2.0.2
285C2B2E36E467DD4D91C8E3C0C0E1750B3FE8CA refs/remotes/origin/tags/release-2.0.1
CBDA99CB45D9ABCB9793DB1D4F70AE562A969F1E refs/remotes/origin/tags/release-2.0.2
A9f074aa89e826d6f9d30808ce5ae3ffe711feda Refs/remotes/origin/tags/release-2.0.2rc1
556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae Refs/remotes/origin/trunk
Git does not do this when cloning from a git server; The following is the look of a tagged warehouse that has just been cloned:
$ git show-ref
c3dcbe8488c6240392e8a5d7553bbffcb0f94ef0 refs/remotes/origin/master
32EF1D1C7CC8C603AB78416262CC421B80A8C2DF refs/remotes/origin/branch-1
75f703a3580a9b81ead89fe1138e6da858c5ba18 refs/remotes/origin/branch-2
23f8588dde934e8f33c263c6d8359b2ae095f863 refs/tags/v0.1.0
7064938bd5e7ef47bfd79a685a62c1e2649e2ce7 refs/tags /v0.2.0
6dcb09b5b57875f334f61aebed695e2e4193db5e refs/tags/v1.0.0
Instead of seeing them as branches, Git grabs tags directly into refs/tags. submit back to Subversion
Now that you have a working warehouse, you can make some changes on the project and then use Git as an SVN client to push your commits upstream. Once you have edited a file and committed it, you have a commit that exists in the local Git repository, which does not exist on the Subversion server:
$ git commit-am ' Adding git-svn instructions to the README '
[master 4AF61FD] Adding GIT-SVN instructions to the READM E
1 file changed, 5 insertions (+)
Next, you need to push the changes upstream. Note how this will change the way you use subversion-you can commit them several times offline and push them to the Subversion server at once. To push to a Subversion server, run the git svn dcommit command:
$ git svn dcommit
committing to file:///tmp/test-svn/trunk ...
M README.txt
Committed r77
m README.txt
r77 = 95e0222ba6399739834380eb10afcd73e0670bc5 (refs/ Remotes/origin/trunk)
No changes between 4af61fd05045e07598c553167e0f31c84fd6ffe1 and Refs/remotes/origin/trunk
resetting to the latest Refs/remotes/origin/trunk
This will take away all the commits you made on top of the Subversion server code, make a Subversion commit for each one, and rewrite your local Git commit to include a unique identifier. This is important because it means that all of your submitted SHA-1 checksums have changed. Partly for this reason, it's not a good idea to use a Git-based project remote version and a Subversion server at the same time. If you view the last commit, a new Git-svn-id is added:
$ git log-1
commit 95e0222ba6399739834380eb10afcd73e0670bc5
Author:ben < Ben@0b684db3-b064-4277-89d1-21af03df0a68>
Date: Thu 03:08:36 +0000
Adding git-svn Instructions to the README
git-svn-id:file:///tmp/test-svn/trunk@77 0b684db3-b064-4277-89d1-21af03df0a68
Note that the SHA-1 checksum you originally submitted originally started with 4AF61FD, and now starts with 95e0222. If you want to push to a Git server and push to a subversion server, you must first push (Dcommit) to the Subversion server, because this action will change your commit data. Pull New Changes
If you work with other developers, when one of you pushes it at some point, another person trying to push the changes will cause a conflict. That change will be rejected until you merge their work. In Git svn, it looks like this:
$ git svn dcommit
committing to file:///tmp/test-svn/trunk ...
ERROR from SVN: Transaction are out of
date:file '/trunk/readme.txt ' are out of date
w:d5837c4b461b7c0e018b49d1239 8769d2bfc240a and Refs/remotes/origin/trunk differ, using rebase:
: 100644 100644 f414c433af0fd6734428cf9d2a9fd8ba00ada145 c80b6127dd04f5fcda218730ddf3a2da4eb39138 M README.txt
Current Branch Master is up to date.
Error:not All changes has been committed into SVN, however the committed
ones (if any) seem-be successfully integ Rated into the working tree.
Please see the above messages for details.
In order to resolve this situation, you can run