Как мне обновить раздвоенный репозиторий GitHub?

2522

Недавно я разветкил проект и применил несколько исправлений. Затем я создал запрос на перенос, который затем был принят.

Несколько дней спустя другое изменение было внесено другим вкладчиком. Так что моя вилка не содержит этого изменения... Как я могу получить это изменение в своей вилке?

Нужно ли мне удалять и воссоздавать свою вилку, когда мне нужно внести дополнительные изменения? Или есть кнопка обновления?

  • 102
    Это также можно сделать из пользовательского интерфейса github. Я хотел бы отдать должное [этому другому постеру] [1]. [1]: stackoverflow.com/a/21131381/728141
  • 2
    Еще одна хорошая запись в блоге об этом - Keeping A GitHub Fork Обновлено
Показать ещё 3 комментария
Теги:
github

15 ответов

2769
Лучший ответ

В вашем локальном клоне вашего разветвленного репозитория вы можете добавить исходный репозиторий GitHub как "remote". ( "Удаления" похожи на прозвища для 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,
# such as upstream/master:

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

Если вы не хотите переписывать историю своей основной ветки (например, потому что другие люди могут ее клонировать), вы должны заменить последнюю команду git merge upstream/master. Тем не менее, для того, чтобы сделать запросы на вытягивание максимально чистыми, вероятно, лучше переупаковать.


Если вы повредили свою ветку на upstream/master, вам может потребоваться принудительное нажатие, чтобы нажать ее в свой собственный разветвленный репозиторий на GitHub. Вы сделали бы это с помощью:

git push -f origin master

Вам нужно использовать -f только после переустановки.

  • 2
    Я добавил +1 к этому ответу, потому что он, вероятно, выполняет то, что действительно нужно автору вопроса. Но я нахожусь в той же ситуации и мне любопытно: есть ли способ на самом деле «вытянуть» из основного репо в мою вилку? Или ветвь апстрима будет обновлена, только если я вернусь к ней после загрузки из апстрима?
  • 81
    Поскольку ваш форк существует только на github, а у github нет инструментов для выполнения слияний через веб-интерфейс, то правильный ответ - локальное слияние вверх по потоку и отправка изменений обратно на ваш форк.
Показать ещё 24 комментария
621

Начиная с мая 2014 года, можно обновить вилку прямо из GitHub. Это все еще работает с сентября 2017 года, НО, что приведет к грязной истории фиксации.

  • Откройте свою вилку на GitHub.
  • Нажмите Pull Requests.
  • Нажмите New Pull Request. По умолчанию GitHub сравнивает оригинал с вашей вилкой, и не должно быть ничего, чтобы сравнивать, если вы не внесли никаких изменений.
  • Нажмите switching the base, если вы видите эту ссылку. В противном случае вручную установите падение base fork на свою вилку и head fork в восходящий поток. Теперь GitHub будет сравнивать вашу вилку с оригиналом, и вы должны увидеть все последние изменения. Изображение 7477
  • Create pull request и назначьте предсказуемое имя вашему запросу на растяжение (например, Update from original).
  • Прокрутите вниз до Merge pull request, но еще не щелкните ничего.

Теперь у вас есть три варианта, но каждый из них приведет к истории нечеткой фиксации.

  • По умолчанию будет создано уродливое объединение слиянием.
  • Если вы нажмете раскрывающийся список и выберите "Сквош и слияние", все промежуточные коммиты будут сжаты в один. Это чаще всего то, чего вы не хотите.
  • Если вы нажмете Rebase and merge, все коммиты будут сделаны "с" вами, оригинальные PR будут ссылаться на ваш PR, а GitHub отобразит This branch is X commits ahead, Y commits behind <original fork>.

Итак, да, вы можете сохранить свое репо с его восходящим потоком, используя веб-интерфейс GitHub, но при этом будет завершена ваша история фиксации. Придерживайтесь командной строки - это легко.

  • 16
    Это работало отлично один раз. Во второй раз этот процесс работал не так: ссылка «Переключение базы» не отображалась. И когда я нажал «Нажмите, чтобы создать запрос на извлечение», он создал PR в репозитории SOURCE. НЕ то, что я хотел ..
  • 25
    Все еще работает (Marchi 2015), хотя ссылки «Переключение базы» больше нет. Вы должны изменить раскрывающийся список «База», чтобы оба указывали на вилку, а затем вы получите приглашение «Сравнить через репозитории», которое приведет вас туда, куда вы хотите.
Показать ещё 13 комментариев
341

Вот официальный документ GitHub на Синхронизация вилки:

Синхронизация вилки

Настройка

Прежде чем вы сможете синхронизировать, вам нужно добавить удаленный элемент, указывающий на восходящий репозиторий. Возможно, вы сделали это, когда вы изначально разветвлялись.

Совет. Синхронизация вилки обновляет только локальную копию репозитория; он не обновляет ваш репозиторий на 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)

Syncing

Для синхронизации вашего репозитория с восходящим потоком требуется два шага: сначала вы должны извлечь из пульта, затем вы должны объединить нужную ветку в свою локальную ветвь.

Fetching

Извлечение из удаленного репозитория приведет к его ветвям и их соответствующим фиксациям. Они хранятся в вашем локальном хранилище под специальными ветвями.

$ git fetch upstream
# Grab the upstream remote 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

Теперь у нас есть ведущая ветвь восходящего потока, хранящаяся в локальной ветки, вверх/вниз

$ 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 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, следуйте инструкциям здесь

  • 1
    Это обновляет мой локальный форк, но мой форк на Github.com по-прежнему говорит «43 коммитов позади». Мне пришлось использовать технику Лобзика, чтобы создать для меня запрос на извлечение, чтобы объединить основные изменения с моей развилкой Github.com.
  • 8
    @MichaelMcGinnis После локального слияния вам придется отправить свои изменения в github. git push origin master
Показать ещё 3 комментария
71

Много ответов в конечном итоге перемещают вашу вилку на одну фиксацию вперед родительского репозитория. Этот ответ суммирует найденные шаги здесь, которые будут переместить вашу вилку в ту же фиксацию, что и родительский.

  • Измените каталог на локальный репозиторий.

    • Перейдите на главную ветку, если вы не git checkout master
  • Добавить родительский объект в качестве удаленного репозитория, git remote add upstream <repo-location>

  • Проблема git fetch upstream
  • Проблема git rebase upstream/master

    • На этом этапе вы проверяете, что фиксирует то, что будет объединено, набрав git status
  • Проблема git push origin master

Подробнее об этих командах см. шаг 3.

  • 11
    @MT: Где вы вводите эти команды, хотя? Суть вопроса, насколько я понимаю, заключается в том, как ресинхронизировать ваш личный форк GitHub с основным проектом, и сделать все это из GitHub . Другими словами, как вы можете обновить свой удаленный форк без локального репозитория?
  • 2
    @JohnY Использование GitHub всегда создает дополнительный коммит. Вы должны сделать все это в оболочке локального репо, чтобы избежать этого дополнительного коммита.
32

С ноября 2013 года был открыт неофициальный запрос функции с GitHub, чтобы попросить их добавить очень простой и интуитивно понятный метод, чтобы локальная вилка синхронизировалась с восходящим потоком:

https://github.com/isaacs/github/issues/121

Примечание. Поскольку запрос функции является неофициальным, также рекомендуется связаться с [email protected], чтобы добавить поддержку для такой функции, как эта, которая будет реализована. Неофициальный запрос функции, указанный выше, может быть использован в качестве доказательства того, насколько интересен этот процесс.

21

Предисловие: Ваша вилка - это "источник", а репозиторий, из которого вы разветвлены, - это "вверх по течению".

Предположим, что вы клонировали уже свою вилку на свой компьютер с помощью следующей команды:

git clone [email protected]:your_name/project_name.git
cd project_name

Если это указано, вам необходимо продолжить в следующем порядке:

  • Добавьте "вверх по течению" в ваш клонированный репозиторий ( "origin" ):

    git remote add upstream [email protected]:original_author/project_name.git
    
  • Извлеките коммиты (и ветки) из "вверх по течению":

    git fetch upstream
    
  • Переключитесь на "ведущую" ветку вилки ( "origin" ):

    git checkout master
    
  • Отметьте изменения вашей ветки "master":

    git stash
    
  • Объедините изменения из "ведущей" ветки "вверх по течению" в свою "основную" ветвь вашего "происхождения":

    git merge upstream/master
    
  • Разрешить конфликты слияния, если они есть, и выполнить слияние

    git commit -am "Merged from upstream"
    
  • Вставьте изменения в свою вилку

    git push
    
  • Верните ваши спрятанные изменения (если есть)

    git stash pop
    
  • Вы закончили! Поздравляем!

GitHub также предоставляет инструкции для этой темы: Синхронизация вилки

  • 0
    Помогло частично: git remote add upstream [email protected]:original_author/project_name.git просто псевдоним для git remote add upstream https://github.com/original_author/project_name.git ?
  • 1
    Волк , думаю, ты уже знаешь это, но для потомков ... Это формат для ssh. help.github.com/articles/configuring-a-remote-for-a-fork
Показать ещё 1 комментарий
17

С даты этого ответа GitHub не имеет (или я уже не говорю?) эту функцию в веб-интерфейсе. Вы можете, однако, попросить [email protected] добавить свой голос для этого.

В то же время пользователь GitHub bardiharborow создал инструмент для этого: https://upriver.github.io/

Источник находится здесь: https://github.com/upriver/upriver.github.io

  • 1
    Хотя я считаю этот инструмент хорошей идеей, реальность такова, что он сломан. Он загрузил только 20 репозиториев из моей учетной записи, и даже нижний колонтитул перенаправляет на сайт, который не существует. Если это будет исправлено, я буду большим защитником.
  • 1
    На сегодняшний день я успешно использовал upriver для синхронизации форка с обратным репозиторием, поэтому он работает для моих целей, и я буду продолжать его использовать.
Показать ещё 1 комментарий
10

Если, как и я, вы никогда не совершаете ничего непосредственно с мастером, что вам действительно нужно, вы можете сделать следующее.

Из локального клона вашей вилки создайте ваш восходящий пульт. Вам нужно сделать это только один раз:

git remote add upstream https://github.com/whoever/whatever.git

Затем, когда вы хотите догнать ветку главного хранилища репозитория, вам необходимо:

git checkout master
git pull upstream master

Предполагая, что вы никогда ничего не совершали на хозяине, вы должны уже сделать. Теперь вы можете нажать локальный мастер на свою удаленную вилку GitHub. Вы также можете переустановить свою ветку разработки на своем современном локальном хозяине.

Итак, перед первоначальной настройкой вверх и главной проверкой все, что вам нужно сделать, это запустить следующую команду для синхронизации вашего ведущего с восходящим потоком: git pull upstream master.

6

Если вы используете GitHub для Windows, то теперь у них есть одна функция щелчка для обновления вилок:

  • Выберите репо в пользовательском интерфейсе.
  • Нажмите кнопку "Обновить от пользователя/ветки" вверху.
  • 0
    Это работает и в Github для Mac.
6

Выполните следующие шаги. Я попробовал их, и это помогло мне.

Оформить покупку в своей ветке

Синтаксис: git филиал yourDevelopmentBranch
Пример: git мастер проверки

Отключить ветку репозитория источника для получения последнего кода

Синтаксис: git pull https://github.com/tastejs/awesome-app-ideas мастер
Пример: git pull https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git BRANCH_NAME

  • 0
    Если вы используете GitHub, вы также можете отправить свои изменения в ветку GitHub. git push HttpsForYourForkOfTheRepo BRANCH_NAME
5

На самом деле, можно создать ветку в своей вилке из любой фиксации восходящего потока в браузере:

  • open https://github.com/<repo>/commits/<hash>, где repo - это ваша вилка, а hash - полный хэш фиксации, который вы можете найти в верхнем веб-интерфейсе. Например, я могу открыть https://github.com/max630/linux/commits/0aa0313f9d576affd7747cc3f179feb097d28990, что указывает на linux master как время написания.
  • нажмите кнопку "Дерево:....".
  • введите имя новой ветки и нажмите Enter

Изображение 7478

Затем вы можете извлечь эту ветку в свой локальный клон, и вам не придется выталкивать все эти данные в верхнем github, когда вы нажимаете правки поверх этой фиксации. Или используйте веб-интерфейс, чтобы что-то изменить в этой ветке.

Как это работает (думаю, я не знаю, как именно это делает github): forks совместно используют хранилище объектов и используют namespaces для разделения ссылок пользователей. Таким образом, вы можете получить доступ ко всем коммитам через свою вилку, даже если они не существовали к моменту форкирования.

  • 1
    Это замечательно! Это позволяет избежать абсолютно бессмысленной загрузки этих коммитов в github.
1

Я обновляю свои разветвленные репозитории с помощью одной строки:

git pull https://github.com/forkuser/forkedrepo.git branch

Используйте это, если вы не хотите добавлять другую удаленную конечную точку в свой проект, как другие решения, размещенные здесь.

  • 1
    Есть ли ограничения на это? то есть применимо ли это только к случаям, когда вы не добавляли коммиты, слияния, запросы на извлечение или с момента последнего обновления объединяли запросы на добавление.
  • 0
    это работает как обычное извлечение из удаленной ветки. Если вы сделали X коммитов в своем локальном репо, и теперь вы Y коммитов за исходным репо, это принесет Y коммитов в ваш локальный филиал и, возможно, даст вам некоторые конфликты для разрешения.
1

В качестве дополнения к этому ответу я искал способ обновить все удаленные ветки отслеживания моего клонированного репо с восходящего потока за один раз. Вот как я это сделал.

Предполагается, что вы уже настроили удаленное указание upstream в исходном репозитории и синхронизировали его с git fetch upstream.

Run:

for branch in $(git ls-remote --heads upstream|sed 's#^.*refs/heads/##'); do git push origin refs/remotes/upstream/$branch:refs/heads/$branch; done

В первой части этой команды будут перечислены все главы в удаленном репо upstream и удалены префикс SHA-1 и /refs/heads/.

Затем для каждой из этих ветвей он надавит локальную копию удаленной ветки (refs/remotes/upstream/<branch>) непосредственно на удаленную ветвь на origin (refs/heads/<branch>).

Любая из этих команд синхронизации ветвей может завершиться по одной из двух причин: либо ветвь upstream была переписана, либо вы наложили фиксацию на эту ветку на свою вилку. В первом случае, когда вы ничего не наделили ветке на своей вилке, безопасно сильно нажимать (git push -f). В другом случае это нормально, когда ветка вилки расходится, и вы не можете ожидать, что команда синхронизации будет работать до тех пор, пока ваши коммиты не будут объединены обратно в upstream.

0

Android Studio теперь научилась работать с репозиториями github fork (вам даже не нужно добавлять удаленный репозиторий "вверх по течению" консольной командой)

Открыть меню VCS → git

и обратите внимание на 2 последних пункта всплывающего меню:

  • Восстановите мою вилку github

  • Создать запрос на растяжение

Попробуйте их. Я успешно использую первый. В любом случае после того, как ветки "вверх по течению" из удаленного репозитория, из которого вы разветвлены, будут доступны в Android Studio, и вы сможете легко работать с ними.

(Я использую Android Studio 3.0 с плагинами "git integration" и "github" )

Изображение 7479

0

Это зависит от размера вашего репозитория и того, как вы его разветвляли.

Если это довольно большой репозиторий, вам, возможно, захотелось управлять им особым образом (например, история перезаписи). В принципе, вы можете получить разницу между текущими и восходящими версиями, зафиксировать их, а затем перетащить вишню на мастер.

Попробуйте прочитать этот. В нем описывается, как обращаться с большими хранилищами Git и как перемещаться по ним с последними изменениями.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню