這是用戶在 2024-6-11 16:39 為 https://gist.github.com/tpwo/621de458d0628f0bc7b7c2564ae65710 保存的雙語快照頁面,由 沉浸式翻譯 提供雙語支持。了解如何保存?
Skip to content
tpwo  /  
Tip: Type # to search pull requests
Type ? for help and tips
Tip: Type # to search issues
Type ? for help and tips
Tip: Type # to search discussions
Type ? for help and tips
Tip: Type ! to search projects
Type ? for help and tips
Tip: Type @ to search teams
Type ? for help and tips
Tip: Type @ to search people and organizations
Type ? for help and tips
Tip: Type > to activate command mode
Type ? for help and tips
Tip: Go to your accessibility settings to change your keyboard shortcuts
Type ? for help and tips
Tip: Type author:@me to search your content
Type ? for help and tips
Tip: Type is:pr to filter to pull requests
Type ? for help and tips
Tip: Type is:issue to filter to issues
Type ? for help and tips
Tip: Type is:project to filter to projects
Type ? for help and tips
Tip: Type is:open to filter to open content
Type ? for help and tips
We’ve encountered an error and some results aren't available at this time. Type a new search or try again later.
No results matched your search
Search for issues and pull requests # Search for issues, pull requests, discussions, and projects # Search for organizations, repositories, and users @ Search for projects ! Search for files / Activate command mode > Search your issues, pull requests, and discussions # author:@me Search your issues, pull requests, and discussions # author:@me Filter to pull requests # is:pr Filter to issues # is:issue Filter to discussions # is:discussion Filter to projects # is:project Filter to open issues, pull requests, and discussions # is:open
@tpwo
Forked from rickyah/using_git-svn.md
Last active May 14, 2021 06:47Report abuse
  • Unstar this gist
    Star this gist
  • Fork this gist
A simple guide to git-svn

Getting started with git-svn
開始使用 git-svn

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

Cloning the SVN repository
克隆 SVN 儲存庫

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

Getting the latest changes from SVN
從 SVN 取得最新更改

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 儲存庫檢索更改,但不將它們套用到本機分支。

Local work 本地工作

Just use your local git repository as a normal git repo, with the normal git commands
只需使用本機 git 儲存庫作為普通 git 儲存庫,並使用普通 git 命令

  • git add FILE and git checkout -- FILE To stage/unstage a file
    git add FILEgit 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 and git stash pop Hell yeah! Stashes are back!
    git stashgit 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 是的!您可以建立本地分公司!但請記得保持歷史線性!

Pushing local changes to SVN
將本地變更推送到 SVN

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 將更改)

Caveats 注意事項

"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.
這意味著您可以進行各種瘋狂的本地操作:分支、刪除/重新排序/壓縮提交、移動歷史記錄、刪除提交等等,但合併除外。

Local 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 伺服器時,它將包含該合併的所有提交的所有更改,因此您將丟失這些提交的歷史記錄,但不會丟失程式碼中的更改。

Handling empty folders properly
正確處理空資料夾

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

Cloning really big SVN repositories
克隆非常大的 SVN 儲存庫

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 儲存庫更快。

About commits and SHA1 關於提交和 SHA1

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 進行本機操作(顯示/比較特定提交、挑選和重設等)

Troubleshooting 故障排除

git svn rebase command issues a checksum mismatch error
git svn rebase 指令發出校驗和不符錯誤

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 推送/拉取數據

File was not found in commit
提交時未找到文件

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>

Further read 進一步閱讀

TODO 全部

@aidan126

Select a reply

Drag to outliner or Upload
Close