[英]How do I update or sync a forked repository on GitHub?
我分叉了一個項目,進行了更改,並創建了一個被接受的拉取請求。 新的提交后來被添加到存儲庫中。 我如何將這些提交放入我的分叉中?
在分叉存儲庫的本地克隆中,您可以將原始 GitHub 存儲庫添加為“遠程”。 (“遠程”就像存儲庫 URL 的昵稱 - 例如, origin
是其中之一。)然后您可以從該上游存儲庫中獲取所有分支,並重新調整您的工作以繼續處理上游版本。 就可能看起來像這樣的命令而言:
# Add the remote, call it "upstream":
git remote add upstream https://github.com/whoever/whatever.git
# Fetch all the branches of that remote into remote-tracking branches
git fetch upstream
# Make sure that you're on your master branch:
git checkout master
# Rewrite your master branch so that any commits of yours that
# aren't already in upstream/master are replayed on top of that
# other branch:
git rebase upstream/master
如果您不想重寫 master 分支的歷史記錄(例如,因為其他人可能已經克隆了它),那么您應該將最后一個命令替換為git merge upstream/master
。 但是,為了進一步提出盡可能干凈的拉取請求,最好重新設置基准。
如果您已將分支重新定位到upstream/master
上,您可能需要強制推送以便將其推送到您自己在 GitHub 上的分叉存儲庫。 你會這樣做:
git push -f origin master
您只需要在重新定位后第一次使用-f
即可。
從 2014 年 5 月開始,可以直接從 GitHub 更新分叉。 這在 2017 年 9 月仍然有效,但它會導致一個骯臟的提交歷史。
Update from original
)。現在您有三個選項,但每個選項都會導致提交歷史不太干凈。
This branch is X commits ahead, Y commits behind <original fork>
。所以是的,你可以使用 GitHub Web UI 讓你的 repo 更新到它的上游,但是這樣做會破壞你的提交歷史。 改用命令行- 這很容易。
這是 GitHub 關於Syncing a fork的官方文檔:
同步分叉
設置
在同步之前,您需要添加一個指向上游存儲庫的遠程。 當你最初分叉時,你可能已經這樣做了。
提示:同步你的 fork 只會更新你的本地倉庫副本; 它不會更新您在 GitHub 上的存儲庫。
$ git remote -v # List the current remotes origin https://github.com/user/repo.git (fetch) origin https://github.com/user/repo.git (push) $ git remote add upstream https://github.com/otheruser/repo.git # Set a new remote $ git remote -v # Verify new remote origin https://github.com/user/repo.git (fetch) origin https://github.com/user/repo.git (push) upstream https://github.com/otheruser/repo.git (fetch) upstream https://github.com/otheruser/repo.git (push)
同步
將存儲庫與上游同步需要兩個步驟:首先必須從遠程獲取,然后必須將所需的分支合並到本地分支。
抓取
從遠程存儲庫中獲取將引入其分支及其各自的提交。 這些存儲在特殊分支下的本地存儲庫中。
$ git fetch upstream # Grab the upstream remote's branches remote: Counting objects: 75, done. remote: Compressing objects: 100% (53/53), done. remote: Total 62 (delta 27), reused 44 (delta 9) Unpacking objects: 100% (62/62), done. From https://github.com/otheruser/repo * [new branch] master -> upstream/master
我們現在將上游的 master 分支存儲在本地分支 upstream/master 中
$ git branch -va # List all local and remote-tracking branches * master a422352 My local commit remotes/origin/HEAD -> origin/master remotes/origin/master a422352 My local commit remotes/upstream/master 5fdff0f Some upstream commit
合並
現在我們已經獲取了上游存儲庫,我們希望將其更改合並到我們的本地分支中。 這將使該分支與上游同步,而不會丟失我們的本地更改。
$ git checkout master # Check out our local master branch Switched to branch 'master' $ git merge upstream/master # Merge upstream's master into our own Updating a422352..5fdff0f Fast-forward README | 9 ------- README.md | 7 ++++++ 2 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 README create mode 100644 README.md
如果您的本地分支沒有任何獨特的提交,git 將改為執行“快進”:
$ git merge upstream/master Updating 34e91da..16c56ad Fast-forward README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
提示:如果您想更新 GitHub 上的存儲庫,請按照此處的說明進行操作
很多答案最終會將您的 fork 移到父存儲庫之前的一個提交。 此答案總結了此處找到的步驟,這些步驟會將您的 fork 移至與 parent 相同的提交。
將目錄更改為您的本地存儲庫。
git checkout master
切換到 master 分支將父級添加為遠程存儲庫, git remote add upstream <repo-location>
git fetch upstream
發出git rebase upstream/master
git status
檢查是否提交了將要合並的內容發出git push origin master
有關這些命令的更多信息,請參閱步驟 3 。
如果像我一樣,你從不直接向 master 提交任何東西,你真的應該這樣做,你可以執行以下操作。
從 fork 的本地克隆,創建上游遠程。 你只需要這樣做一次:
git remote add upstream https://github.com/whoever/whatever.git
然后,每當您想趕上上游存儲庫主分支時,您需要:
git checkout master
git pull upstream master
假設你自己從來沒有在 master 上做過任何事情,你應該已經完成了。 現在,您可以將本地 master 推送到您的源遠程 GitHub 分支。 您還可以在您現在最新的本地 master 上重新設置您的開發分支。
通過初始上游設置和主節點結帳,您需要做的就是運行以下命令以將您的主節點與上游同步: git pull upstream master 。
前言:你的 fork 是“起源”,而你 fork 的存儲庫是“上游”。
假設您已經使用以下命令將 fork 克隆到您的計算機:
git clone git@github.com:your_name/project_name.git
cd project_name
如果給出了,那么您需要按以下順序繼續:
將“上游”添加到您的克隆存儲庫(“來源”):
git remote add upstream git@github.com:original_author/project_name.git
從“上游”獲取提交(和分支):
git fetch upstream
切換到 fork 的“master”分支(“origin”):
git checkout master
存儲“master”分支的更改:
git stash
將“上游”的“master”分支的更改合並到“origin”的“master”分支中:
git merge upstream/master
解決合並沖突(如果有)並提交合並
git commit -am "Merged from upstream"
將更改推送到您的 fork
git push
取回隱藏的更改(如果有)
git stash pop
你完成了! 恭喜!
GitHub 還提供了有關此主題的說明:同步分叉
自 2013 年 11 月以來,GitHub 收到了一個非官方的功能請求,要求他們添加一種非常簡單直觀的方法來保持本地分支與上游同步:
https://github.com/isaacs/github/issues/121
注意:由於功能請求是非官方的,因此建議您聯系support@github.com
以添加您對要實現的此類功能的支持。 上面的非官方功能請求可以用作對此正在實施的興趣量的證據。
GitHub 現在推出了一項功能,只需單擊按鈕即可同步分叉。
轉到您的 fork,單擊Fetch upstream
,然后單擊Fetch and merge
以直接將您的 fork 與其父 repo 同步。
您也可以單擊“ Compare
”按鈕在合並之前比較更改。
參考:GitHub 的文檔
有三種方法可以做到這一點:從 Web UI(選項 1)、從 GitHub CLI(選項 2)或從命令行(選項 3)。
選項 1 - 網頁界面
在 GitHub 上,導航到要與上游存儲庫同步的分叉存儲庫的主頁。
選擇獲取上游下拉菜單。
- 查看來自上游存儲庫的提交的詳細信息,然后單擊 Fetch and merge。
選項 2 - GitHub CLI
要從其父分支更新遠程分支,請使用gh repo sync
子命令並提供您的分支名稱作為參數。
$ gh repo sync owner/cli-fork
如果上游存儲庫的更改導致沖突,則 GitHub CLI 無法同步。 您可以設置-force
標志以覆蓋目標分支。
選項 3 - 命令行
在將一個分支與上游存儲庫同步之前,必須在 Git 中配置一個指向上游存儲庫的遠程。
1 打開 Git Bash。
2 將當前工作目錄更改為您的本地項目。
3 從上游存儲庫獲取分支及其各自的提交。 對 BRANCHNAME 的提交將存儲在本地分支 upstream/BRANCHNAME 中。
$ git fetch upstream
> remote: Counting objects: 75, done.
> remote: Compressing objects: 100% (53/53), done.
> remote: Total 62 (delta 27), reused 44 (delta 9)
> Unpacking objects: 100% (62/62), done.
> From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY
> * [new branch] main -> upstream/main
4 檢查你的 fork 的本地默認分支 - 在這種情況下,我們使用 main。
$ git checkout main
> Switched to branch 'main'
5 將上游默認分支(在本例中為 upstream/main)中的更改合並到本地默認分支中。 這將使您的 fork 的默認分支與上游存儲庫同步,而不會丟失您的本地更改。
$ git merge upstream/main
> Updating a422352..5fdff0f
> Fast-forward
> README | 9 -------
> README.md | 7 ++++++
> 2 files changed, 7 insertions(+), 9 deletions(-)
> delete mode 100644 README
> create mode 100644 README.md
如果一個本地分支沒有任何獨特的提交,Git 將改為執行“快進”:
$ git merge upstream/main
> Updating 34e91da..16c56ad
> Fast-forward
> README.md | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
注意:同步一個人的分叉只會更新一個人的本地副本。 要在 GitHub.com 上更新一個分支,必須推送一個更改。
如果您使用 GitHub for Windows 或 Mac,那么現在它們具有一鍵更新 forks 的功能:
實際上,可以從瀏覽器中上游的任何提交在您的 fork 中創建一個分支:
https://github.com/<repo>/commits/<hash>
,其中repo是您的 fork, hash是提交的完整哈希,您可以在上游 Web 界面中找到它。 例如,我可以打開https://github.com/max630/linux/commits/0aa0313f9d576affd7747cc3f179feb097d28990 ,它指向linux
master
作為寫作時間。然后,您可以將該分支獲取到您的本地克隆,當您在該提交之上推送編輯時,您不必將所有數據推送回 GitHub。 或者使用 Web 界面更改該分支中的某些內容。
它是如何工作的(這是一個猜測,我不知道 GitHub 到底是怎么做的):forks 共享對象存儲並使用命名空間來分隔用戶的引用。 因此,您可以通過您的 fork 訪問所有提交,即使它們在分叉時不存在。
請按照以下步驟操作。 我嘗試了它們,它幫助了我。
結帳到您的分行
語法: git branch yourDevelopmentBranch
示例: git checkout master
拉取源代碼庫分支以獲取最新代碼
語法: git pull https://github.com/tastejs/awesome-app-ideas master
示例: git pull https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git BRANCH_NAME
我用這一行更新了我的分叉回購:
git pull https://github.com/forkuser/forkedrepo.git branch
如果您不想將另一個遠程端點添加到您的項目中,請使用此選項,就像此處發布的其他解決方案一樣。
作為對這個答案的補充,我正在尋找一種方法來一次從上游分支更新我克隆的 repo ( origin ) 的所有遠程分支。 我就是這樣做的。
這假設您已經配置了一個指向源存儲庫( origin從中分叉的地方)的上游遠程,並已將其與git fetch upstream
同步。
然后運行:
for branch in $(git ls-remote --heads upstream|sed 's#^.*refs/heads/##'); do git push origin refs/remotes/upstream/$branch:refs/heads/$branch; done
該命令的第一部分列出了上游遠程 repo 中的所有頭,並刪除了 SHA-1,后跟refs/heads/
分支名稱前綴。
然后對於這些分支中的每一個,它將上游遠程跟蹤分支的本地副本(本地端的refs/remotes/upstream/<branch>
)直接推送到源端的遠程分支(遠程端的refs/heads/<branch>
)。
這些分支同步命令中的任何一個都可能由於以下兩個原因之一失敗:上游分支已被重寫,或者您已將該分支上的提交推送到您的 fork。 在第一種情況下,您沒有向 fork 上的分支提交任何內容,強制推送是安全的(添加-f開關;即git push -f
在上面的命令中)。 在另一種情況下,這是正常的,因為您的 fork 分支已經發散,並且在您的提交合並回upstream之前,您不能期望 sync 命令起作用。
“Pull”應用程序是一種自動設置和忘記的解決方案。 它會將你的 fork 的默認分支與上游存儲庫同步。
訪問 URL,單擊綠色的“安裝”按鈕並選擇要啟用自動同步的存儲庫。
該分支每小時直接在 GitHub 上更新一次,在您的本地機器上,您需要拉取 master 分支以確保您的本地副本是同步的。
如果你設置你的上游。 檢查git remote -v
,就足夠了。
git fetch upstream
git checkout master
git merge --no-edit upstream/master
git push
克隆分叉存儲庫后,轉到克隆所在的目錄路徑和 Git Bash 終端中的幾行。
$ cd project-name
$ git remote add upstream https://github.com/user-name/project-name.git
# Adding the upstream -> the main repo with which you wanna sync
$ git remote -v # you will see the upstream here
$ git checkout master # see if you are already on master branch
$ git fetch upstream
你可以走了。 主存儲庫中的所有更新更改都將推送到您的 fork 存儲庫中。
“fetch”命令對於在項目中保持最新是必不可少的:只有在執行“git fetch”時,您才會被告知您的同事推送到遠程服務器的更改。
您仍然可以訪問此處進行進一步查詢
假設你的 fork 是https://github.com/me/foobar並且原始存儲庫是https://github.com/someone/foobar
訪問https://github.com/me/foobar/compare/master...someone:master
如果您看到綠色文本Able to merge
然后按Create pull request
在下一頁上,滾動到頁面底部,然后單擊Merge pull request和Confirm merge 。
使用此代碼段生成鏈接以同步您的分叉存儲庫:
new Vue ({ el: "#app", data: { yourFork: 'https://github.com/me/foobar', originalRepo: 'https://github.com/someone/foobar' }, computed: { syncLink: function () { const yourFork = new URL(this.yourFork).pathname.split('/') const originalRepo = new URL(this.originalRepo).pathname.split('/') if (yourFork[1] && yourFork[2] && originalRepo[1]) { return `https://github.com/${yourFork[1]}/${yourFork[2]}/compare/master...${originalRepo[1]}:master` } return 'Not enough data' } } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> Your fork URL: <input size=50 v-model="yourFork" /> <br /> Original repository URL: <input v-model="originalRepo" size=50 /> <br /> Link to sync your fork: <a :href="syncLink">{{syncLink}}</a> </div>
$ git remote add upstream https://github.com/....
$ git pull upstream main
$ git push
這取決於您的存儲庫的大小以及您如何分叉它。
如果它是一個相當大的存儲庫,您可能希望以一種特殊的方式來管理它(例如刪除歷史記錄)。 基本上,您可以獲得當前版本和上游版本之間的差異,提交它們,然后將它們挑選回 master。
試試看 這個。 它描述了如何處理大型 Git 存儲庫以及如何使用最新更改將它們上傳到上游。
最初,分叉的存儲庫有一個名為master
的分支。 如果您正在開發新功能或修復,您通常會創建一個新的分支feature
並進行更改。
如果您希望分叉存儲庫與父存儲庫同步,您可以為Pull 應用程序(在功能分支中)設置一個配置文件( pull.yml
),如下所示:
version: "1"
rules:
- base: feature
upstream: master
mergeMethod: merge
- base: master
upstream: parent_repo:master
mergeMethod: hardreset
這使分叉存儲庫的master
分支與父存儲庫保持同步。 它通過合並相同的分叉存儲庫的master
分支來保持分叉存儲庫的feature
分支更新。 這假設feature
分支是包含配置文件的默認分支。
這里有兩種合並hardreset
mergemethods
它有助於強制在分叉的 repo 的master
分支中與父 repo 同步更改,另一種方法是merge
。 此方法用於合並您在feature
分支中所做的更改以及由於master
分支中的強制同步而完成的更改。 在合並沖突的情況下,拉取應用程序將允許您在拉取請求期間選擇下一個操作過程。
您可以在此處閱讀有關基本和高級配置以及各種mergemethods
的信息。
保持分叉存儲庫始終保持更新有兩個主要方面。
1. 從 fork master 創建分支並在那里進行更改。
因此,當您的Pull Request被接受時,您可以安全地刪除分支,因為當您使用上游更新它時,您貢獻的代碼將存在於您的分叉存儲庫的主庫中。 這樣,您的 master 將始終處於干凈狀態,可以創建一個新分支來進行另一次更改。
2.為fork master創建一個計划的工作來自動更新。
這可以通過cron來完成。 如果您在 linux 中執行此操作,這是一個示例代碼。
$ crontab -e
將此代碼放在crontab file
中,以每小時執行一次作業。
0 * * * * sh ~/cron.sh
然后創建cron.sh
腳本文件和與ssh-agent和/或期望的git 交互,如下所示
#!/bin/sh
WORKDIR=/path/to/your/dir
REPOSITORY=<name of your repo>
MASTER="git@github.com:<username>/$REPOSITORY.git"
UPSTREAM=git@github.com:<upstream>/<name of the repo>.git
cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent` && expect ~/.ssh/agent && ssh-add -l
git clone $MASTER && cd $REPOSITORY && git checkout master
git remote add upstream $UPSTREAM && git fetch --prune upstream
if [ `git rev-list HEAD...upstream/master --count` -eq 0 ]
then
echo "all the same, do nothing"
else
echo "update exist, do rebase!"
git reset --hard upstream/master
git push origin master --force
fi
cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent -k`
檢查您的分叉存儲庫。 它會不時顯示此通知:
這個分支甚至與
<upstream>
:master 。
使用這些命令(在幸運的情況下)
git remote -v
git pull
git fetch upstream
git checkout master
git merge upstream/master --no-ff
git add .
git commit -m"Sync with upstream repository."
git push -v
如果你想讓你的 GitHub 分支與各自的上游保持同步,還有專門為 GitHub 提供的這個 probot 程序: https ://probot.github.io/apps/pull/ 可以完成這項工作。 您需要在您的帳戶中允許安裝,這將使您的分叉保持最新。
如何在本地機器上更新你的分叉倉庫?
首先,檢查您的遙控器/主機
git remote -v
你應該有起源和上游。 例如:
origin https://github.com/your___name/kredis.git (fetch)
origin https://github.com/your___name/kredis.git (push)
upstream https://github.com/rails/kredis.git (fetch)
upstream https://github.com/rails/kredis.git (push)
之后轉到主要:
git checkout main
並從上游合並到主要:
git merge upstream/main
rm -rf oldrepository
git clone ...
可能有更微妙的選擇,但這是我確信我的本地存儲庫與上游相同的唯一方法。
從 github 頁面刪除您的遠程開發人員
然后應用這些命令:
1) git branch -D dev
2) git fetch upstream
3) git checkout master
4) git fetch upstream && git fetch upstream --prune && git rebase upstream/master && git push -f origin master
5) git checkout -b dev
6) git push origin dev
7) git fetch upstream && git fetch upstream --prune && git rebase upstream/dev && 8) git push -f origin dev
要查看您的配置,請使用以下命令:
git remote -v
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.