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

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

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

Как я могу получить это изменение в моей вилке? Нужно ли мне удалять и заново создавать мой форк, когда у меня появятся дальнейшие изменения? Или есть кнопка обновления?

Ответ 1

В локальном клоне вашего разветвленного репозитория вы можете добавить исходный репозиторий GitHub в качестве "удаленного". ("Remotes" подобны псевдонимам для URL репозиториев - например, origin - один.) Затем вы можете извлечь все ветки из этого репозитория upstream и перебазировать свою работу, чтобы продолжить работу над версией upstream. С точки зрения команд, которые могут выглядеть так:

# 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

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

  • Откройте свою вилку на GitHub.
  • Нажмите Pull Requests.
  • Нажмите New Pull Request. По умолчанию GitHub сравнивает оригинал с вашей вилкой, и не должно быть ничего, чтобы сравнивать, если вы не внесли никаких изменений.
  • Нажмите switching the base, если вы видите эту ссылку. В противном случае вручную установите падение base fork на свою вилку и head fork в восходящий поток. Теперь GitHub будет сравнивать вашу вилку с оригиналом, и вы должны увидеть все последние изменения. введите описание изображения здесь
  • 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, но при этом будет завершена ваша история фиксации. Придерживайтесь командной строки - это легко.

Ответ 3

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

Ответ 4

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

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

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

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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 также предоставляет инструкции для этой темы: Синхронизация вилки

Ответ 7

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

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

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

Тогда всякий раз, когда вы хотите догнать ветку основной ветки репозитория, вам необходимо:

git checkout master
git pull upstream master

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

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

Ответ 8

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

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

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

Ответ 9

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

  1. Выберите хранилище в пользовательском интерфейсе.
  2. Нажмите кнопку "Обновить от пользователя/ветки" вверху.

Ответ 10

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

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

Enter image description here

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

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

Ответ 11

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

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

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

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

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

Ответ 12

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

Предполагается, что вы уже настроили удаленный входящий поток, указывающий на исходный репозиторий (откуда был разветвлен источник), и синхронизировали его с 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

Первая часть этой команды перечисляет все головы в удаленном репо восходящего направления и удаляет SHA-1, за которым следует префикс refs/heads/ name name.

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

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

Ответ 13

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

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

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

Ответ 14

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

Откройте меню VCS → Git

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

  • Перебазировать мою вилку GitHub

  • Создать запрос на извлечение

Попробуйте их. Я использую первый для синхронизации моего локального хранилища. В любом случае ветки из родительского удаленного репозитория ("upstream") будут доступны в Android Studio после того, как вы нажмете "Rebase my GitHub fork", и вы сможете легко с ними работать.

(Я использую Android Studio 3.0 с подключаемыми модулями Git и GitHub.)

Enter image description here

Ответ 15

Когда вы клонировали свой разветвленный репозиторий, перейдите в путь к каталогу, где находится ваш клон, и в несколько строк в вашем Git Bash Terminal.

$ 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" вы будете информированы об изменениях, которые ваши коллеги отправили на удаленный сервер.

Вы все еще можете посетить здесь для дальнейших запросов

Ответ 16

Это зависит от размера вашего хранилища и от того, как вы его разветкили.

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

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

Ответ 17

Если вы установите свой апстрим. Проверьте с помощью git remote -v, тогда этого будет достаточно.

git fetch upstream
git checkout master
git merge --no-edit upstream/master
git push

Ответ 18

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

1. Создайте ветки из master-вилки и внесите в них изменения.

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

2. Создайте запланированное задание, чтобы мастер разветвления автоматически обновлялся.

Это можно сделать с помощью cron. Вот пример кода, если вы делаете это в Linux.

$ crontab -e

поместите этот код в crontab file чтобы выполнять работу каждый час.

0 * * * * sh ~/cron.sh

затем создайте cron.sh сценария cron.sh и git-взаимодействие с ssh-agent и/или ожидайте, как cron.sh ниже

#!/bin/sh
WORKDIR=/path/to/your/dir   
REPOSITORY=<name of your repo>
MASTER="[email protected]:<username>/$REPOSITORY.git"   
[email protected]:<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.

enter image description here