`
leonzhx
  • 浏览: 791737 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Chapter 8. Git and Other Systems

阅读更多

1.   git svn allows you to use Git as a valid client to a Subversion server, so you can use all the local features of Git and then push to a Subversion server as if you were using Subversion locally.

 

 

2.   Subversion can have only a single linear history, and confusing it is very easy. It's generally best to keep your history as linear as possible by rebasing your work and avoiding doing things like simultaneously interacting with a Git remote repository. Don't rewrite your history and try to push again.

 

3.   git svn clone command imports an entire Subversion repository into a local Git repository:

$ git svn clone http://progit-example.googlecode.com/svn/ -T trunk -b branches -t tags

This runs the equivalent of two commands—git svn init followed by git svn fetch   — on the URL you provide. The -T trunk -b branches -t tags   part tells Git that this Subversion repository follows the basic branching and tagging conventions. If you name your trunk, branches, or tags differently, you can change these options. Because this is so common, you can replace this entire part with –s :

$ git svn clone file:///tmp/test-svn -s

 

4.   git svn assumes that you won't have multiple remotes and saves all its references to points on the remote server with no namespacing. You can use the Git plumbing command show-ref   to look at all your full reference names:

$ git show-ref

1cbd4904d9982f386d87f88fcelc24ad7c0f0471 refs/heads/master

aeelecc263l8l64f355a883f5d99cffOc852d3c4 refs/remotes/my-calc-branch

03d09bOe2aad427e34a6d50ff147128e76cOeOf5 refs/remotes/tags/2.0.2

50d02ccOadc9da4319eeba0900430ba219b9c376 refs/remotes/tags/release-2.0.1

4caaa711a50c77879a91b8b90380060f672745cb refs/remotes/tags/release-2.0.2

1c4cb508l44c513ffl214c3488abe66dcb929l6f refs/remotes/tags/release-2.0.2rcl

1cbd4904d9982f386d87f88fcelc24ad7c0f0471 refs/remotes/trunk

Tags are added as remote branches, not as real Git tags.

 

5.   You can do several commits offline and then push them all at once to the Subversion server. To push to a Subversion server, you run the git svn dcommit command. This takes all the commits you've made on top of the Subversion server code, does a Subversion commit for each, and then rewrites your local Git commit to include a unique identifier. This is important because it means that all the SHA-1 checksums for your commits change. If you look at the last commit, you can see the new git-svn-id that was added:

$ git log 1

commit 938bla547c2cc92033b74d32030e86468294a5c8

Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>

Date:   Sat May 2 22:06:44 2009 +0000

 

    Adding git-svn instructions to the README

 

    git-svn-id:  file:///tmp/test-svn/trunk@79 4c93b258-373f-11de-be05-5f7a86268029

  

If you want to push to both a Git server and a Subversion server, you have to push (dcommit ) to the Subversion server first, because that action changes your commit data.

 

6.   git svn rebase pulls down any changes on the server that you don't have yet and rebases any work you have on top of what is on the server.

 

7.   Unlike Git, which requires you to merge upstream work you don't yet have locally before you can push, git svn   makes you do that only if the changes conflict. If someone else pushes a change to one file and then you push a change to another file, your dcommit will work fine. The outcome is a project state that didn't exist on either of your computers when you pushed.

 

8.   You can run git svn fetch   to grab the new data, but git svn rebase does the fetch and then updates your local commits. You need to be sure that your working directory is clean when you run git svn rebase . If you have local changes, you must either stash your work or temporarily commit it before running git svn rebase   —otherwise, the command will stop if it sees that the rebase will result in a merge conflict.

 

9.  R unning dcommit   on a master branch which has merged in topic branch commits works fine, except that when you look at your Git project history, it hasn't rewritten any of the commits on topic branch, instead, all those changes appear in the SVN version of the single merge commit. When someone else clones that work, all they see is the merge commit with all the work squashed into it; they don't see the commit data about where it came from or when it was committed.

 

10.   To create a new branch in Subversion, you run:

$ git svn branch opera

    This does the equivalent of the svn copy trunk branches/opera   command in Subversion and operates on the Subversion server. It's important to note that it doesn't check you out into that branch; if you commit at this point, that commit will go to trunk on the server, not opera .

 

11.   Git figures out what branch your dcommits go to by looking for the tip of any of your Subversion branches in your history—you should have only one, and it should be the last one with a git-svn-id in your current branch history.

 

13.   You can run git svn log   to view your commit history in SVN formatting. It only shows you commits that have been committed up to the Subversion server. It works offline and is more like the last known state of the commits on the Subversion server.

 

14.   You can get the equivalent of svn annotate by running git svn blame [FILE] . Again, it doesn't show commits that you did locally in Git or that have been pushed to Subversion by others in the meantime.

 

15.   You can also get the same sort of information that svn info   gives you by running git svn info . It runs offline and is up to date only as of the last time you communicated with the Subversion server.

 

16.  git svn create-ignore automatically creates corresponding .gitignore files according to svn:ignore properties of the SVN server for you so your next commit can include them. You can also run:

$ git svn show-ignore >  .git/info/exclude

That way, you don't litter the project with .gitignore files. This is a good option if you're the only Git user on a Subversion team, and your teammates don't want .gitignore files in the project.

 

----- Migrating To Git -----

 

17.   You need a mapping from the Subversion users to the Git authors. Create a file called users.txt   that has this mapping in a format like this:

schacon = Scott Chacon <schacon@geemail.com>

selse = Someo Nelse <selse@geemail.com>

To get a list of the author names that SVN uses, you can run this:

$ svn log --xml | grep author | sort -u | perl -pe  's/.>(.?)<./$l = /'

And then you can import the SVN history to your git repo:

$ git-svn clone http://my-project.googlecode.com/svn/   --authors-file=users.txt --no-metadata -s my_project

--no-metadata tells Git not to include metadata that Subversion normally imports. Now not only does the Author field look a lot better( in a Git convention), but the git-svn-id is no longer there, either.

 

18.   You'll move the tags so they're actual tags(light-weight) rather than strange remote branches, and then you'll move the rest of the branches so they're local:

$ cp -Rf .git/refs/remotes/tags/* .git/refs/tags/

$ rm -Rf .git/refs/remotes/tags

$ cp -Rf .git/refs/remotes/* .git/refs/heads/

$ rm -Rf .git/refs/remotes

 

19.   The last thing to do is add your new Git server as a remote and push to it. Because you want all your branches and tags to go up, you can run this:

$ git push origin --all

 

20.   A Perforce importer is also distributed with Git, but only in the contrib   section of the source code—it isn't available by default like git svn . To run it, you must get the Git source code:

$ git clone git://git.kernel.org/pub/scm/git/git.git

$ cd git/contrib/fast-import

To set up your client, you must export the P4P0RT   environment variable to point to the Perforce depot:

$ export P4P0RT=public.perforce.com:l666

Run the git-p4 clone   command under fast-import folder to import the project from the Perforce server: (You must have Python and the p4   tool installed on your machine for this import to work.)

$ git-p4 clone //public/jam/src@all /opt/p4import

If you go to the /opt/p4import directory and run git log , you can see the git-p4   identifier in each commit which tracks the Perforce depot path and change number. You can use git filter-branch to remove the identifier strings:

$ git filter-branch --msg-filter ' sed -e "/^\[git-p4:/d"'

 

21.   Quality importers are available for CVS, Clear Case, Visual Source Safe, even a directory of archives. If none of these tools works for you, you have a rarer tool, or you otherwise need a more custom importing process, you should use git fast-import . This command reads simple instructions from stdin to write specific Git data. All you have to do is tell fast-import   what the content snapshots are, what commit data points to them, and the order they go in.

 

22.   The input for git fast-import looks like:

commit refs/heads/master

mark :l

committer Scott Chacon <schacon@geemail.com> 1230883200 −0700

data 29

imported from back_2009_01_02deleteall

M 644 inline file.rb

data 12

version two

commit refs/heads/master

mark :2

committer Scott Chacon <schacon@geemail.com> 1231056000 −0700

data 29

imported from back_2009_01_04from :1

deleteall

M 644 inline file.rb

data 14

version three

M 644 inline new.rb

data 16

new version one

(...)

The format is like:

commit [branch]

mark: [mark]

commiter [author] [date]-[timezone]

data [commit-message-size]

[commit-message]

deleteall

M [file-mode] inline [file-path]

data [file-size]

[file contents]

mark is the fast-import   term for an identifier you give to a commit; as you create commits, you give each one a mark that you can use to link to it from other commits.

 

23.   Because many systems think of their revisions as changes from one commit to another, fast-import   can also take commands with each commit to specify which files have been added, removed, or modified and what the new contents are. You could calculate the differences between snapshots and provide only this data, but doing so is more complex—you may as well give Git all the data and let it figure it out. If this is better suited to your data, check the fast-import   man page for details about how to provide your data in this manner.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics