git-svn is a git command that allows using git to interact with Subversion repositories.
git-svn 是一個 git 指令,允許使用 git 與 Subversion 儲存庫互動。
git-svn is part of git, meaning that is NOT a plugin but actually bundled with your git installation.
SourceTree also happens to support this command so you can use it with your usual workflow.
git-svn 是 git 的一部分,這意味著它不是一個插件,但實際上與您的 git 安裝捆綁在一起。 SourceTree 也恰好支援此命令,因此您可以在通常的工作流程中使用它。
Reference: https://git-scm.com/book/en/v2/Git-and-Other-Systems-Git-as-a-Client
參考:https://git-scm.com/book/en/v2/Git-and-Other-Systems-Git-as-a-Client
You need to create a new local copy of the repository with the command
您需要使用以下命令建立儲存庫的新本機副本
git svn clone SVN_REPO_ROOT_URL [DEST_FOLDER_PATH] -T TRUNK_REPO_PATH -t TAGS_REPO_PATH -b BRANCHES_REPO_PATH
If your SVN repository follows the standard layout (trunk, branches, tags folders) you can save some typing:
如果您的 SVN 儲存庫遵循標準佈局(主幹、分支、標籤資料夾),您可以節省一些輸入:
git svn clone -s SVN_REPO_ROOT_URL [DEST_FOLDER_PATH]
git-svn clone
checks out each SVN revision, one by one, and makes a git commit in your local repository in order to recreate the history.
If the SVN repository has a lot of commits this will take a while, so you may want to grab a coffee.
git-svn clone
逐一檢查每個 SVN 修訂版,並在本機儲存庫中進行 git 提交以重新建立歷史記錄。如果 SVN 儲存庫有很多提交,這將需要一段時間,因此您可能想喝杯咖啡。
When the command is finished you will have a full fledged git repository with a local branch called master that tracks the trunk branch in the SVN repository.
命令完成後,您將擁有一個完整的 git 儲存庫,其中有一個名為 master 的本機分支,用於追蹤 SVN 儲存庫中的主幹分支。
If the SVN repository has a long history, the git svn clone
operation can crash or hang (you'll notice the hang becasue the progress will stall, just kill the process with CTRL-C).
如果 SVN 儲存庫具有較長的歷史記錄, git svn clone
操作可能會崩潰或掛起(您會注意到掛起,因為進度將停止,只需使用 CTRL-C 終止進程即可)。
If this happens, worry not: the git repository has been created, but there is some SVN history yet to be retrieved from the server.
To resume the operation, just change to the git repository's folder and issue the command git svn fetch
.
如果發生這種情況,請不要擔心:git 儲存庫已創建,但還有一些 SVN 歷史記錄尚未從伺服器檢索。要恢復操作,只需更改到 git 存儲庫的資料夾並發出命令 git svn fetch
。
The equivalent to git pull
is the command git svn rebase
.
與 git pull
等效的是指令 git svn rebase
。
This retrieves all the changes from the SVN repository and applies them on top of your local commits in your current branch.
This works like, you know, a rebase between two branches :)
這將從 SVN 儲存庫中檢索所有更改,並將它們應用到目前分支中的本機提交之上。這就像是兩個分支之間的變基:)
You can also use git svn fetch
to retrieve the changes from the SVN repository but without applying them to your local branch.
您也可以使用 git svn fetch
從 SVN 儲存庫檢索更改,但不將它們套用到本機分支。
Just use your local git repository as a normal git repo, with the normal git commands
只需使用本機 git 儲存庫作為普通 git 儲存庫,並使用普通 git 命令
git add FILE
andgit checkout -- FILE
To stage/unstage a file
git add FILE
和git checkout -- FILE
暫存/取消暫存文件git commit
To save your changes. Those commits will be local and will not be "pushed" to the SVN repo
git commit
儲存您的變更。這些提交將是本地的,不會被「推送」到 SVN 儲存庫git stash
andgit stash pop
Hell yeah! Stashes are back!
git stash
和git stash pop
天哪!藏品回來了!git reset HEAD --hard
Revert all your local changes
git reset HEAD --hard
恢復所有本機更改git log
Access all the history in the repository
git log
存取儲存庫中的所有歷史記錄git rebase -i
Yep, you can squash all the commits! (as usual be SUPER CAREFULL with this one)
git rebase -i
是的,你可以壓縮所有提交! (像往常一樣,對此要非常小心)git branch
Yes! you can create local branches! But remember to keep the history linear!
git branch
是的!您可以建立本地分公司!但請記得保持歷史線性!
git svn dcommit --rmdir
will create a SVN commit for each of your local git commits.
As with SVN, your local git history must be in sync with the latest changes in the SVN repository, so if the command fails, try performing a git svn rebase
first.
git svn dcommit --rmdir
將為每個本地 git 提交建立一個 SVN 提交。與 SVN 一樣,您的本機 git 歷史記錄必須與 SVN 儲存庫中的最新變更同步,因此如果命令失敗,請先嘗試執行 git svn rebase
。
Side note 邊註
Your local git commits will be rewritten when using the command git svn dcommit
.
This command will add a text to the git commit's message referencing the SVN revision created in the SVN server, which is VERY useful.
However, adding a new text requires modifying an existing commit's message which can't actually be done: git commits are inmutable.
The solution is create a new commit with the same contents and the new message, but it is technically a new commit anyway (i.e. the git commit's SHA1 will change)
使用命令 git svn dcommit
時,您的本機 git 提交將被重寫。此命令將在 git commit 訊息中新增一條文本,引用 SVN 伺服器中建立的 SVN 修訂版本,這非常有用。然而,新增文字需要修改現有提交的訊息,而這實際上是不可能完成的:git 提交是不可變的。解決方案是創建一個具有相同內容和新訊息的新提交,但從技術上講它無論如何都是一個新提交(即 git 提交的 SHA1 將更改)
"Subversion is a system that is far less sophisticated than Git" so you can't use all the full power of git without messing up the history in the Subversion server.
Fortunately the rules are very simple:
“Subversion 是一個遠不如 Git 複雜的系統”,因此您無法在不弄亂 Subversion 伺服器中的歷史記錄的情況下使用 git 的全部功能。幸運的是,規則非常簡單:
Keep the history linear 保持歷史線性
That's it. 就是這樣。
This means you can make all kind of crazy local operations: branches, removing/reordering/squashing commits, move the history around, delete commits, etc anything but merges.
這意味著您可以進行各種瘋狂的本地操作:分支、刪除/重新排序/壓縮提交、移動歷史記錄、刪除提交等等,但合併除外。
Do not merge your local branches, if you need to reintegrate the history of local branches use git rebase
instead.
不要合併本地分支,如果需要重新整合本地分支的歷史記錄,請使用 git rebase
代替。
When you perform a merge, a merge commit is created.
The particular thing about merge commits is that they have two parents, and that makes the history non-linear.
Non-linear history will confuse SVN in the case you "push" a merge commit to the repository.
當您執行合併時,會建立合併提交。合併提交的特殊之處在於它們有兩個父級,這使得歷史記錄非線性。如果您將合併提交「推送」到儲存庫,非線性歷史記錄將使 SVN 感到困惑。
However do not worry: you won't break anything if you "push" a git merge commit to SVN.
不過不用擔心:如果你將 git merge 提交「推送」到 SVN,你不會破壞任何東西。
If you do so, when the git merge commit is sent to the svn server it will contain all the changes of all commits for that merge, so you will lose the history of those commits, but not the changes in your code.
如果這樣做,當 git merge 提交發送到 svn 伺服器時,它將包含該合併的所有提交的所有更改,因此您將丟失這些提交的歷史記錄,但不會丟失程式碼中的更改。
git does not recognice the concept of folders, it just works with files and their filepaths.
This means git does not track empty folders.
SVN, however, does. Using git-svn means that, by default, any change you do involving empty folders with git will not be propagated to SVN.
git 不識別資料夾的概念,它只適用於檔案及其檔案路徑。這意味著 git 不會追蹤空資料夾。然而 SVN 卻可以。使用 git-svn 意味著,預設情況下,您使用 git 對空資料夾所做的任何變更都不會傳播到 SVN。
Fortunately the --rmdir
flag corrects this issue, and makes git remove an empty folder in SVN if you remove the last file inside of it. Unfortunatelly it does not removes existing empty folders, you need to do it manually.
幸運的是, --rmdir
標誌修正了這個問題,如果您刪除其中的最後一個文件,則 git 會刪除 SVN 中的空資料夾。不幸的是,它不會刪除現有的空資料夾,您需要手動執行此操作。
To avoid needing to issue the flag each time you do a dcommit, or to play it safe if you are using a git GUI tool (like SourceTree) you need to set this behaviour as default, just issue the command:
為了避免每次執行 dcommit 時都需要發出該標誌,或者為了安全起見(如果您使用的是 git GUI 工具(如 SourceTree)),您需要將此行為設為預設行為,只需發出命令:
git config --global svn.rmdir true
This changes your .gitconfig file and adds these lines:
這會更改您的 .gitconfig 檔案並新增以下行:
[svn]
rmdir = true
Be careful if you issue the command git clean -d
.
That will remove all untracked files including folders that should be kept empty for SVN.
如果發出指令 git clean -d
請小心。這將刪除所有未追蹤的文件,包括應為 SVN 保留為空的資料夾。
If you need to generate againg the empty folders tracked by SVN use the command git svn mkdirs
.
如果您需要再次產生 SVN 追蹤的空資料夾,請使用指令 git svn mkdirs
。
In practices this means that if you want to cleanup your workspace from untracked files and folders you should always use both commands:
在實踐中,這意味著如果您想清除工作區中未追蹤的文件和資料夾,您應該始終使用這兩個命令:
git clean -fd && git svn mkdirs
If you SVN repo history is really really big this operation could take hours, as git-svn needs to rebuild the complete history of the SVN repo.
如果您的 SVN 儲存庫歷史記錄真的很大,此操作可能需要幾個小時,因為 git-svn 需要重建 SVN 儲存庫的完整歷史記錄。
Fortunately you only need to clone the SVN repo once; as with any other git repository you can just copy the repo folder to other collaborators.
Copying the folder to multiple computers will be quicker that just cloning big SVN repos from scratch.
幸運的是,您只需要克隆 SVN 儲存庫一次;與其他 git 儲存庫一樣,您只需將儲存庫資料夾複製給其他協作者即可。將資料夾複製到多台電腦比從頭開始複製大型 SVN 儲存庫更快。
As git commits created for git-svn are local, the SHA1 ids for git commits is only work locally.
This means that you can't use a SHA1 to reference a commit for another person because the same commit will have a diferent SHA1 in each machine.
由於為 git-svn 建立的 git 提交是本地的,因此 git 提交的 SHA1 id 只能在本地使用。這意味著您不能使用 SHA1 來引用另一個人的提交,因為同一提交在每台機器上都會有不同的 SHA1。
You need to rely in svn revision number.
The number is appended to the commit message when you push to the SVN server
您需要依賴 svn 修訂號。當您推送到 SVN 伺服器時,該編號會附加到提交訊息中
You can use the SHA1 for local operations though (show/diff an specific commit, cherry-picks and resets, etc)
不過,您可以使用 SHA1 進行本機操作(顯示/比較特定提交、挑選和重設等)
The command git svn rebase throws an error similar to this:
指令 git svn rebase 會引發類似以下內容的錯誤:
Checksum mismatch: <path_to_file> <some_kind_of_sha1>
expected: <checksum_number_1>
got: <checksum_number_2>
The solution to this problem is reset svn to the revision when the troubled file got modified for the last time, and do a git svn fetch so the SVN history is restored.
The commands to perform the SVN reset are:
此問題的解決方案是將 svn 重設為上次修改有問題的文件時的修訂版本,並執行 git svn fetch 以便恢復 SVN 歷史記錄。執行 SVN 重置的命令是:
- git log -1 --
<path_to_file>
(copy the SVN revision number that appear in the commit message)
git log -1 --<path_to_file>
(複製提交訊息中出現的 SVN 修訂號) - git svn reset
<revision_number>
git svn 重設<revision_number>
- git svn fetch git svn 獲取
You should be able to push/pull data from SVN again
您應該能夠再次從 SVN 推送/拉取數據
When you try to fetch or pull from SVN you get an error similar to this
當您嘗試從 SVN 取得或拉取時,您會收到與此類似的錯誤
<file_path> was not found in commit <hash>
This means that a revision in SVN is trying to modify a file that for some reason doesn't exists in your local copy.
The best way to get rid of this error is force a fetch ignoring the path of that file and it will updated to its status in the latest SVN revision:
這意味著 SVN 中的修訂版正嘗試修改由於某種原因在本機副本中不存在的檔案。消除此錯誤的最佳方法是強制執行忽略該檔案的路徑的提取,它將更新為最新 SVN 版本中的狀態:
git svn fetch --ignore-paths <file_path>
- https://git-scm.com/docs/git-svn
- https://engineering.icf.com/how-to-setup-a-two-way-sync-between-svn-and-git/
- how to deal with authors file, based on https://stackoverflow.com/questions/2159567/what-is-the-format-of-an-authors-file-for-git-svn-specifically-for-special-char
如何處理作者文件,根據https://stackoverflow.com/questions/2159567/what-is-the-format-of-an-authors-file-for-git-svn-specially-for-special-char