如果你只是要恢复一个文件(修复未提交文件中的错误),如”hello.rb”, 你就要使用 git checkout
$ git checkout -- hello.rb
git clone --depth=1 git://github.com/imatix/zguide.git
Create a shallow clone with a history truncated to the specified number of revisions. A shallow repository has a number of limitations (you cannot clone or fetch from it, nor push from nor into it), but is adequate if you are only interested in the recent history of a large project with a long history, and would want to send in fixes as patches.
Git and SVN treat tags differently. Tags are a powerful feature in Git, but just a folder in SVN, much like how branches are.
So to create tags in SVN from git-svn, you have to create a branch (tag) in git-svn repo. Git tags will not be "dcommitted"
You can use git svn branch –tag or its shorthand git svn tag to create tags and then dcommit them.
Related question with detailed answer: Git-svn: create & push a new branch/tag?
Exporting a project to a Git repository
–dry-run (-n)
# Create SVN branch called "my_topic" git svn branch -m "Topic branch" my_topic # Create the Git branch for "my_topic" git checkout --track -b my-topic remotes/my_topic # Hack hack hack... # Make sure you're committing to the right SVN branch git svn dcommit --dry-run # Commit changes to "my_topic" branch in SVN git svn dcommit
svn update
git svn rebase
svn commit
git svn dcommit
clone
git svn clone file:///tmp/test-svn -T trunk -b branches -t tags
其中-T trunk -b branches -t tags 告诉 Git 该 Subversion 仓库遵循了基本的分支和标签命名法则。如果你的主干(译注:trunk,相当于非分布式版本控制里的master分支,代表开发的主线),分支或者标签以不同的方式命名,则应做出相应改变。由于该法则的常见性,可以使用 -s 来代替整条命令,它意味着标准布局(s 是 Standard layout 的首字母),也就是前面选项的内容。下面的命令有相同的效果:
git svn clone file:///tmp/test-svn -s
git svn tag tag_name
此时创建的tag是直接在服务器将当前分支拷贝到tags目录,所以在此之前一定要将本地的修改推送到服务器,否则会将打错tag。
记得dcommit!
要在 Subversion 中建立一个新分支,需要运行 git svn branch [分支名] :
git svn branch opera
这相当于在 Subversion 中的 svn copy trunk branches/opera 命令,并会对 Subversion 服务器进行相关操作。值得注意的是它没有检出和转换到那个分支;如果现在进行提交,将提交到服务器上的 trunk, 而非 opera。
Git 通过搜寻提交历史中 Subversion 分支的头部来决定 dcommit 的目的地——而它应该只有一个,那就是当前分支历史中最近一次包含 git-svn-id 的提交。
如果需要同时在多个分支上提交,可以通过导入 Subversion 上某个其他分支的 commit 来建立以该分支为 dcommit 目的地的本地分支。比如你想拥有一个并行维护的 opera 分支,可以运行
git branch opera remotes/opera git checkout opera # or git checkout -b opera refs/remotes/opera
然后,如果要把 opera 分支并入 trunk (本地的 master 分支),可以使用普通的 git merge。不过最好提供一条描述提交的信息(通过 -m),否则这次合并的记录是 Merge branch opera ,而不是任何有用的东西。 记住,虽然使用了 git merge 来进行这次操作,并且合并过程可能比使用 Subversion 简单一些(因为 Git 会自动找到适合的合并基础),这并不是一次普通的 Git 合并提交。最终它将被推送回 commit 无法包含多个祖先的 Subversion 服务器上;因而在推送之后,它将变成一个包含了所有在其他分支上做出的改变的单一 commit。把一个分支合并到另一个分支以后,你没法像在 Git 中那样轻易的回到那个分支上继续工作。提交时运行的 dcommit 命令擦除了全部有关哪个分支被并入的信息,因而以后的合并基础计算将是不正确的—— dcommit 让 git merge 的结果变得类似于 git merge –squash。不幸的是,我们没有什么好办法来避免该情况—— Subversion 无法储存这个信息,所以在使用它作为服务器的时候你将永远为这个缺陷所困。为了不出现这种问题,在把本地分支(本例中的 opera)并入 trunk 以后应该立即将其删除。
# Create alias for checkout command: git config alias.co checkout # Make sure that you local branches are up to date: git co master # checkout branch that tracks subversion's trunk git svn rebase git co local/foo # checkout branch that tracks subversion's branches/foo # It assumes that the branch is created with the command: # `git co -b local/foo remotes/foo` # And the repo was created with: # `git svn clone --stdlayout SVN_REPO_URL` git svn rebase # Merge branches: # create new local branch based on `master` git co master git co -b merging_branch_foo # merge, resolve conflicts, etc (pure git) git merge local/foo # rebase `merging_branch_foo` to linearize history for subversion git rebase master # or `rebase -i` # merge `merging_branch_foo` into `master` git co master # git merge merging_branch_foo # --squash to create single commit git merge --no-ff # no fast-forward. This will force git to create a merge commit, which can then be dcommitted to svn. # commit changes to svn git svn dcommit # (optionally) delete `merging_branch_foo` git branch -D merging_branch_foo
git-svn: reset tracking for master
Currently, it is not possible to delete an SVN branch using git-svn. But it is easy to delete the branch using SVN, without even having to check it out. So simply type
svn rm $URL/branches/the_branch
Please note that deleting a Subversion branch does not cause it to be deleted from the git-svn repository. (This is intentional, because deleting a Subversion branch does not cause any information loss, whereas deleting a git branch causes its existence to be forgotten following the next git garbage collection.) So if you want the remote SVN branch to be deleted from your git repository, you have to do it manually:
git branch -D -r the_branch rm -rf .git/svn/the_branch
To delete a git branch that corresponds to a Subversion tag, the commands are slightly different:
git branch -D -r tags/the_tag rm -rf .git/svn/tags/the_tag
git svn 工具集在当前不得不使用 Subversion 服务器或者开发环境要求使用 Subversion 服务器的时候格外有用。不妨把它看成一个跛脚的 Git,然而,你还是有可能在转换过程中碰到一些困惑你和合作者们的迷题。为了避免麻烦,试着遵守如下守则:
保持一个不包含由 git merge 生成的 commit 的线性提交历史。将在主线分支外进行的开发通通衍合回主线;避免直接合并。
不要单独建立和使用一个 Git 服务来搞合作。可以为了加速新开发者的克隆进程建立一个,但是不要向它提供任何不包含 git-svn-id 条目的内容。甚至可以添加一个 pre-receive 挂钩来在每一个提交信息中查找 git-svn-id 并拒绝提交那些不包含它的 commit。
如果遵循这些守则,在 Subversion 上工作还可以接受。然而,如果能迁徙到真正的 Git 服务器,则能为团队带来更多好处。
To undo git add .
,use git reset
。
可以使用一些Git软件如Gitosis。
不过也可以直接运行:
git clone --bare my_project my_project.git # same as cp -Rf my_project/.git my_project.git # by ssh scp -r my_project.git user@git.example.com:/opt/git git clone user@git.example.com:/opt/git/my_project.git
如果某个 SSH 用户对 /opt/git/my_project.git 目录有写权限,那他就有推送权限。
git config --global --unset core.gitproxy
export GIT_PROXY_COMMAND="~/bin/proxy-wrapper"
git submodule add git://github.com/chneukirchen/rack.git rack
git submodule deinit asubmodule git rm asubmodule # Note: asubmodule (no trailing slash) # or, if you want to leave it in your working tree git rm --cached asubmodule
How do I remove a Git submodule?
在用git-svn或者某些外部程序调用git的时候,有时候会导致git丢失一些log。但是丢失log并不带代表是丢失commit,我们只需要找回以前的commit就行了。
利用reflog,我们很容易可以找到所有的commit,然后我们就可以将master之类的游标reset到我们想要去到的commit。
git reflog git reset --hard 1e35a3
git diff --name-status master..file_buffer
git config [--global] user.email "me@here.com"
git config --global color.diff auto
git config --global color.ui true
To remove a submodule you need to:
From: How do I remove a Git submodule?
git tag -d v1.0 git push --delete origin v1.0
git push origin --delete <branchName> git push origin :<branchName>
假设我们已经有了socks5代理
Host github.com ProxyCommand nc -x 127.0.0.1:8989 -X 5 %h %p
git config --global core.excludesfile '~/.gitignore'
然后在~/.gitignore
里面添加全局忽略
$ git commit ... (1) $ git reset --soft "HEAD^" (2) $ edit (3) $ git add .... (4) $ git commit -c ORIG_HEAD (5)
How to undo the last Git commit?
# checkout from branch develop git checkout develop -- VideoEncoder.cpp