簡體   English   中英

如何從 git 存儲庫中刪除作者?

[英]How do I remove an author from a git repository?

如果我創建了一個 Git 存儲庫並公開發布它(例如在 GitHub 等上),並且我收到來自該存儲庫貢獻者的請求,無論出於何種原因刪除或隱藏他們的名字,有沒有辦法輕松做到這一點?

基本上,我有這樣的請求,可能想用“匿名貢獻者”之類的東西替換他們的姓名和電子郵件地址,或者他們的電子郵件地址的 SHA-1 哈希或類似的東西。

Jeff 說得很對,正確的軌道是 git filter-branch。 它需要一個使用環境變量的腳本。 對於您的用例,您可能需要這樣的東西:

git filter-branch --env-filter '
    if [ "$GIT_AUTHOR_NAME" = "Niko Schwarz" ]; then \
        export GIT_AUTHOR_NAME="Jon Doe" GIT_AUTHOR_EMAIL="john@bugmenot.com"; \
    fi
    '

您可以測試它的工作方式如下:

$ cd /tmp
$ mkdir filter-branch && cd filter-branch
$ git init
Initialized empty Git repository in /private/tmp/filter-branch/.git/
$ 
$ touch hi && git add . && git commit -m bla
[master (root-commit) 081f7f5] bla
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hi
$ echo howdi >> hi && git commit -a -m bla
[master a466a18] bla
 1 files changed, 1 insertions(+), 0 deletions(-)
$ git log
commit a466a18e4dc48908f7ba52f8a373dab49a6cfee4
Author: Niko Schwarz <niko.schwarz@gmail.com>
Date:   Thu Aug 12 09:43:44 2010 +0200

    bla

commit 081f7f50921edc703b55c04654218fe95d09dc3c
Author: Niko Schwarz <niko.schwarz@gmail.com>
Date:   Thu Aug 12 09:43:34 2010 +0200

    bla
$ 
$ git filter-branch --env-filter '
> if [ "$GIT_AUTHOR_NAME" = "Niko Schwarz" ]; then \    
> export GIT_AUTHOR_NAME="Jon Doe" GIT_AUTHOR_EMAIL="john@bugmenot.com"; \
> fi
> '
Rewrite a466a18e4dc48908f7ba52f8a373dab49a6cfee4 (2/2)
Ref 'refs/heads/master' was rewritten
$ git log
commit 5f0dfc0dc9a325a3f3aaf4575369f15b0fb21fe9
Author: Jon Doe <john@bugmenot.com>
Date:   Thu Aug 12 09:43:44 2010 +0200

    bla

commit 3cf865fa0a43d2343b4fb6c679c12fc23f7c6015
Author: Jon Doe <john@bugmenot.com>
Date:   Thu Aug 12 09:43:34 2010 +0200

    bla

請小心。 如果不使所有以后的提交哈希無效,就無法刪除作者的姓名。 這將使以后合並對一直使用您的存儲庫的人來說是一件痛苦的事情。

如果您不得不為一個用戶而是所有用戶“匿名化”一個 git 存儲庫,Git 2.2(2014 年 11 月)通過改進和增強的git fast-export提供了一個有趣的功能:

請參閱Jeff King ( peff ) 的commit a872275commit 75d3d65

fast-export --anonymize選項:

有時用戶想報告他們在存儲庫中遇到的錯誤,但他們不能隨意共享存儲庫的內容。
如果他們能夠生成一個與其歷史和樹具有相似形狀的存儲庫,但不會泄露任何信息,那將會很有用。
然后可以與開發人員共享這個“匿名”存儲庫(假設它仍然復制原始問題)。

此補丁為fast-export實現了一個“ --anonymize ”選項,它生成一個可以重新創建這樣的存儲庫的流。
生成單個流使調用者可以輕松驗證他們沒有泄漏任何有用的信息。 您可以通過運行以下命令來大致了解將要共享的內容:

git fast-export --anonymize --all |
perl -pe 's/\d+/X/g' |
sort -u |
less

這將顯示我們生成的每條唯一行,以任何數字為模(每個匿名標記都分配了一個數字,例如“ User 0 ”,我們在輸出中一致地替換它)。

除了匿名化之外,這會產生相對較小(與原始存儲庫相比)且生成速度較快(與使用filter-branch或自己修改fast-export的輸出相比)的測試用例

文件:

如果給出了--anonymize選項,git 將嘗試從存儲庫中刪除所有標識信息,同時仍然保留足夠的原始樹和歷史模式來重現一些錯誤。

使用此選項,git 將使用匿名數據替換輸出中的所有引用名稱、路徑、blob 內容、提交和標記消息、名稱和電子郵件地址
相同字符串的兩個實例將被等效替換(例如,具有相同作者的兩次提交將在輸出中具有相同的匿名作者,但與原始作者字符串沒有相似之處)。
提交、分支和標簽之間的關系以及提交時間戳是 +retained(但提交消息和引用名稱與原始信息沒有相似之處)。
樹的相對構成被保留(例如,如果您有一個包含 10 個文件和 3 個樹的根樹,那么輸出也會如此),但它們的名稱和文件的內容將被替換。


另請參閱 Git 2.28(2020 年第 3 季度),“ git fast-export --anonymize ”學會了采用自定義映射,以允許其用戶調整其輸出,使其更適用於調試。

提交f39ad38提交8a49495提交65b5d9f (2020年6月25日),並提交d5bf91f提交6416a86提交55b0145提交a0f6564提交7f40759提交750bb32提交b897bf5提交b8c0689 (2020年6月23日),由傑夫·金( peff .
(由Junio C gitster合並-- gitster -- in commit 0a23331 ,2020 年 7 月 6 日)

fast-export :允許播種匿名映射

幫助者:Eric Sunshine
簽字人:Jeff King

將存儲庫匿名化后,可能很難找到原始和結果之間對應的提交,因此很難重現觸發原始錯誤的命令。

讓我們讓匿名化地圖的種子成為可能。
這讓用戶可以:

  • 將名稱標記為按原樣保留,如果他們不認為它們是秘密的(在這種情況下,它們的原始命令將起作用)
  • 將名稱映射到新值,這使他們可以在不泄露原始名稱的情況下將復制配方調整為新名稱

實現是相當簡單的。
我們已經將每個匿名標記存儲在一個哈希圖中(這樣相同的標記出現兩次會轉換為相同的結果)。 我們可以引入一個新的“種子”哈希圖,它首先被咨詢。

這確實向用戶做出了更多關於我們將如何匿名化事物的承諾(例如,令牌分割路徑名)。 但是,即使單個令牌的實際匿名化發生變化,我們也不太可能想要更改這些規則。 並且它使用戶更容易,他們可以只取消一個目錄名,而不必指定其中的每個路徑。

這種方法的一種替代方法是按照我們認為合適的方式進行匿名化,然后將整個 refname 和路徑名映射轉儲到一個文件中。 這確實有效,但使用起來有點尷尬(您必須手動從映射中挖掘您關心的項目)。

git fast-export現在有:

--anonymize-map=<from>[:<to>] :

在匿名輸出中將標記<from>轉換為<to>
如果省略<to> ,則將<to> <from>映射到自身(即,不要對其進行匿名化)。

重現一些錯誤可能需要引用特定的提交或路徑,這在引用名稱和路徑被匿名化后變得具有挑戰性。
您可以要求將特定令牌保持原樣或映射到新值。

例如,如果您有一個使用git rev-list sensitive -- secret.c重現的錯誤,您可以運行:

 --------------------------------------------------- $ git fast-export --anonymize --all \\ --anonymize-map=sensitive:foo \\ --anonymize-map=secret.c:bar.c \\ >stream ---------------------------------------------------

導入流后,您可以在匿名存儲庫中運行git rev-list foo -- bar.c

請注意,路徑和引用名稱在斜杠邊界處拆分為標記。
上面的命令會將subdir/secret.c匿名subdir/secret.c類似path123/bar.c東西; 然后,您可以在匿名存儲庫中搜索bar.c以確定最終路徑名。

為了使引用最終路徑名更簡單,您可以映射每個路徑組件; 因此,如果您還將subdir匿名publicdir ,則最終路徑publicdir/bar.cpublicdir/bar.c

您可以在本地存儲庫中進行更改, git commit --amend適當的提交(添加名稱的位置),然后git push --force以使用您的存儲庫版本更新 github。

具有貢獻者姓名的原始提交仍將在 reflog 中可用(直到它過期,但需要花費很多精力才能找到它。如果這是一個問題,您也可以從 reflog 中刪除該特定提交——請參閱git help reflog的語法以及如何在列表中找到它。

如果您想更改多個提交,請查看手冊頁以了解

git filter-branch --env-filter

您可以使用 git-filter-branch 來更改先前提交的內容/元。

請注意,由於您不是在處理本地分支(它已被推送到 github),因此您無法從已經克隆您的分支的任何人中刪除作者。

修改已經發布的分支通常也是一種不好的做法,因為它會導致跟蹤分支的人感到困惑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM