我在网上阅读了大量的“从 svn 到 git”和其他“git-svn 工作流程”文章,但我仍然认为它们经常处理过于简单的情况。它们通常针对那些只想在本地使用 git 和 hack 的人,而不使用 git 的全部功能,例如在多个开发人员之间进行拉、取、合并等操作,这些开发人员都使用 git-svn 克隆了 svn 存储库,然后仍然希望能够随时将他们的更改推送到(官方)svn 存储库,并返回到 git 中工作并分享他们的东西等。
每当这些文章承认你无法完成在纯 git 中所做的所有事情时,后果和可能发生的事情从来没有得到明确的解释(或者也许只是我?)。甚至 git-svn 手册页也提到了警告,但并不是很广泛。
根据我所读到的内容,我觉得以特定方式使用 git-svn 时可能会出现问题,我将在下面描述。有人可以告诉我我的说法是否正确吗?
这是“想要的”做事方式:
- 我们在 svn 存储库中有一个项目
- 开发人员 git-svn-clone 是 svn 存储库。他开始在本地破解
- 开发人员 B git-svn-clone 的相同 svn 存储库。他开始自己破解一些东西。
- 这样做一段时间后,可能会添加开发人员 C/D/...,并且让其他执行“标准”svn 的开发人员提交到原始存储库,git 用户会希望共享他们的代码并执行各种 git 魔法。
- 这些 git 用户中的任何一个都希望能够将现在合并的更改推送到 svn (dcommit?)
我的问题是:我在做梦吗?我前段时间在一本 git 书中读到,我认为 git-svn-clone 可以创建 git 存储库,这些存储库当然是 svn 存储库的“镜像”,但不同开发人员以这种方式创建的 git 存储库会有不同的“ ids”和提交将具有不同的哈希值。所以我的理解是,这些 git 存储库不会共享任何共同的 git 祖先,因此无法使用您需要共享、合并等的所有 git 命令。这是真的吗?我们会面临这个工作流程的问题吗?
有时我读到这可以做到,至少使用一个“官方”裸 git 存储库,这将是唯一一个被 git-svn 克隆的存储库,所有 git 用户都必须从这个存储库开始。然后,您需要有人负责这个中央 git 存储库,并在将所有内容提交到 svn 存储库之前收集 git 开发人员之间的更改。这将是 git 用户“不知道”原始 git 存储库来自 svn 的唯一方法,并让他们可以随心所欲地使用所有 git 命令。唯一需要精通 git 和 svn (并且了解 git-svn 注意事项)的人是“合并经理”(或者无论他被称为什么)。
我是否完全误解了 git-svn 警告?有没有更简单的方法来做到这一点?
I've read a great deal of "go from svn to git" and other "git-svn workflow" articles on the web, and still I think they often deal with overly simple situations. They are often targeted at guys who just want to use git and hack locally, without using the full power of git, like pull, fetch, merge and the like between multiple developers who would all have cloned the svn repository with git-svn, then still expect to be able to push their changes any time to the (official) svn repository, and get back to working in git and sharing their stuff etc.
Whenever these articles admit you can't do everything you'd do in pure git, the consequences and possible screw ups are never clearly explained (or maybe it's just me ?). Even the git-svn man page mentions caveats, but not really in an extensive manner.
Based on what I've read, I feel there could be problems when git-svn is used in that specific way, which I'll describe below. Can someone tell me if I'm right about this ?
Here is the "wanted" way of doing things:
- We have a project in a svn repository
- Developer A git-svn-clone's the svn repo. He begins to hack things locally
- Developer B git-svn-clone's the same svn repo. He begins to hack things on his own.
- After doing that for some time, possibly adding devs C/D/..., and having other developers who do "standard" svn commits to the original repo, the git users would want to share their code and do all kinds of git magic.
- Any one of those git users would like to be able to push the now merged changes to svn (dcommit?)
My question is: am I dreaming? I read some time ago, in a git book I think, that git-svn-clone could create git repositories that are of course a "mirror" of the svn repo, but that git repos created that way by different developers would have different "ids" and commits would have different hashes. So my understanding was that those git repos wouldn't share any common git ancestor, and thus wouldn't be able to use all the git commands you need to share, merge, and so on. Is it true, are we going to face problems with this workflow ?
Sometimes I read this could be done, using at least an "official" bare git repository, that would be the only one to be git-svn-cloned, and all git users would have to start form this one. Then you need someone who is in charge of this central git repo, and gathers the changes between the git devs, before dcommiting everything to the svn repo. This would be the only way for git users to be "unaware" that the original git repo comes from svn, and would let them use all git commands as they like. The only person who would need to be fluent in both git and svn (and know about git-svn caveats) would be the "merge manager" (or whatever he's called).
Am I completely misunderstanding git-svn caveats ? Is there any simpler way of doing this ?
发布评论
评论(7)
我最近对此进行了很多尝试,并且认为我设法想出了一个有点工作的设置。是的,这是一个严格的 rebase-only 制度,是的,它很复杂,但你确实可以使用 Git 在本地工作(速度、历史记录、存储、索引等)。
我认为,当你与团队中的其他 Git 用户协作时,你可以在幕后使用分支,但我个人还没有对此进行太多实验。只要在提交之前将日志线性化,它就应该可以工作。
这是简短的版本(重复了很多已经说过的内容):
git svn init svnurl
配置 git-svn 远程,并且git update-ref refs/remotes/git-svn refs/remotes/origin/master
因此 git-svn 有一个指向修订版的指针git svn dcommit
首先必须重复上面的update-ref
,以防来自 SVN 的更新版本。此页面上有一个工作流程说明(我需要更多声誉点才能内联图像)。更新:我们开始:
I've been experimenting a lot with this lately, and think I managed to come up with a setup that somewhat works. Yes, it's a strict rebase-only regime, yes it's complicated, but you do get to use Git for working locally (speed, history, stash, index, etc).
You can use branches behind the scenes when you collaborate with other Git users in your team I think, but haven't personally experimented too much with this. As long as you linearize the log before dcommitting it should work.
Here's the short version (repeats a lot what's been already said):
git svn init svnurl
to configure the git-svn remote, andgit update-ref refs/remotes/git-svn refs/remotes/origin/master
so git-svn has a pointer to a revisiongit pull --rebase
git svn dcommit
first have to repeat theupdate-ref
above in case of newer revisions coming from SVN.There's an illustration of the workflow on this page (I need more reputation points before I can inline the image). Update: Here we go:
问题当然是第4步。 dcommit 尝试将本地历史记录重播到服务器。 Dcommit 假装您是 SVN 客户端。现在,如果您提交的代码不仅仅来自您,那么就很难提交到 SVN。
以下是大师就此事所写的内容:
The problem is step 4 of course. A dcommit tries to replay your local history to the server. Dcommit pretends that you're a SVN client. Now, if the code you're dcommitting isn't only from you, that's something that is hard to dcommit to SVN.
Here's what the guru writes on the matter:
我以前所做的,是创建一个初始的 git svn 克隆,然后使用 git 在开发人员之间共享他的 .git,所以我们有完全相同的引用。
它似乎工作正常,因为我们能够在 git 用户之间使用“特定的 git 功能”,只要我们保持在线性树中(即变基而不是合并)。
What I used to do, is create an initial git svn clone, then shared he .git among the developpers using git, so we had exactly the same references.
It seemed to work correctly as we were able to use "specific git features" between git users, as long as we stayed in a linear tree (ie rebasing instead of merging).
有一个工具可以解决共享与 Subversion 存储库同步的 Git 存储库的问题。
SubGit 是一个 Git-SVN 双向服务器端镜像。
人们可以将 SubGit 安装到 Subversion 存储库中,并使 Git 存储库自动与 SVN 同步:
SubGit 将预提交和后提交挂钩安装到 Subversion 存储库中,将预接收和后接收挂钩安装到 Git 存储库中。因此,它会立即翻译来自 SVN 和 Git 端的传入修改。安装 SubGit 后,开发人员可以使用任何 Git 客户端来克隆和使用 Git 存储库。
SubGit 不依赖于 git-svn,它使用我们团队开发的自己的翻译引擎。有关这方面的更多详细信息,您可以在 SubGit 与 git-svn 比较中找到。有关 SubGit 的一般文档可在此处获取。
SubGit 1.0 版本需要本地访问 Subversion 存储库,即 SVN 和 Git 存储库必须驻留在同一主机上。但在 2.0 版本中,我们将引入 Git 代理模式,此时 Subversion 和 Git 存储库可以位于任何地方,并且只有 Git 存储库安装了 SubGit,即 Subversion 存储库保持不变。
SubGit 是一个商业产品。对于开源学术项目以及最多 10 名提交者的项目来说,它是免费的。
免责声明:我是 SubGit 开发人员之一。
There's a tool that solves the problem of sharing Git repository synchronized with Subversion repository.
SubGit is a Git-SVN bi-directional server-side mirror.
One may install SubGit into Subversion repository and get Git repository automatically synchronized with SVN:
SubGit installs pre-commit and post-commit hooks into Subversion repository, pre-receive and post-receive hooks into Git repository. As result it immediately translates incoming modifications from SVN and Git sides. After SubGit installation developers may use any Git client to clone and work with Git repository.
SubGit does not rely on git-svn, it uses its own translation engine our team has developed. More details on this you may find at SubGit vs. git-svn comparison. General documentation on SubGit is available here.
Version 1.0 of SubGit needs local access to Subversion repository, i.e. SVN and Git repositories have to reside on the same host. But with version 2.0 we're going to introduce Git proxy mode, when Subversion and Git repositories can be located anywhere and only Git repositories have SubGit installed into them, i.e. Subversion repositories remain untouched.
SubGit is a commercial product. It is free for open-source, academic project and also for projects with up to 10 committers.
Disclaimer: I'm one of SubGit developers.
一旦您涉及“分布式”问题,您最好在开发人员之间克隆一个裸露的 git 存储库。
关于公共 SVN 存储库的导出-导入阶段,供其他人使用,脚本
git2svn 和 svn2git 可以帮助封装魔法。
使用 Git 和 SVN 存储库时的其他注意事项可在问题 “git 的工作流程和帮助、2 个 svn 项目和一个“工作副本””
As soon as you step in "distributed" issue, you are better off with one bare git repo cloned amongst developers.
Regarding the export-import phase to the public SVN repo, for other to use, the scripts
git2svn and svn2git can help encapsulate the magic.
Other considerations when working in Git and SVN repos are found in the question "Workflow and help with git, 2 svn projects and a single “workcopy”"
我发现这篇博文建议保留一个单独的用于与 Subversion 存储库同步的分支,这样仍然可以在 master 分支中进行推/拉操作。
I found this blog post that suggests keeping a separate branch for syncing with the Subversion repository, such that it will still be possible to do push/pull in the master branch.
我认为 git-svn 的问题之一是它将 git-svn-id 存储在提交注释中;因为这会重写该提交,它会更改它的 SHA1,因此您无法将其推送到人们将共享它的任何地方。
我实际上更喜欢 bzr-svn,因为它使用 SVN 修订属性功能将 bzr revid 存储在远程 SVN 修订中,这意味着没有本地修订重写。它还具有所需的属性,即同一 SVN 分支的两次独立拉取将产生相同且可互操作的 bzr 分支。
One of the problems I perceive with git-svn is that it stores the git-svn-id in the commit comment ; because this rewrites that commit, it changes it's SHA1, so you can't push it anywhere people will be sharing it.
I actually prefer bzr-svn because instead it stores the bzr revid in the remote SVN revision using the SVN revision properties feature instead which means no local revision rewrite. It also has the property desired, that two independent pulls of the same SVN branch will result in identical and interoperable bzr branches.