Как вытащить удаленную ветку из чужого репо

266

У меня есть проект, размещенный на GitHub, который кто-то подписал. На своей вилке они создали новую ветку "foo" и внесли некоторые изменения. Как мне перенести их "foo" в новую ветку, также называемую "foo" в моем репо?

Я понимаю, что они могли бы отправить мне запрос на извлечение, но я бы хотел сам инициировать этот процесс.

Предположим следующее:

  1. Поскольку они раздвоили мой проект, оба наших репо имеют одинаковую «историю»
  2. Хотя GitHub показывает, что их проект был разветвлен от моего, мой локальный репозиторий не имеет никаких ссылок на проект этого человека. Нужно ли добавлять их как удаленный?
  3. У меня пока нет ветки с именем "foo" - я не знаю, нужно ли мне сначала создавать это вручную.
  4. Я определенно хочу, чтобы это вытащили в отдельную ветку, а не моего мастера.
Колин О'Делл
источник

Ответы:

349
git remote add coworker git://path/to/coworkers/repo.git
git fetch coworker
git checkout --track coworker/foo

Это настроит локальную ветку foo, отслеживая удаленную ветку coworker/foo. Поэтому, когда ваш коллега внес некоторые изменения, вы можете легко их извлечь:

git checkout foo
git pull

Ответ на комментарии:

Круто :) А если я захочу внести свои изменения в эту ветку, я должен создать вторую локальную ветку "bar" из "foo" и работать там, а не прямо на моем "foo"?

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

git branch --set-upstream foo colin/foo

при условии, colinчто ваш репозиторий (удаленный от вашего репозитория коллег) определен аналогично:

git remote add colin git://path/to/colins/repo.git
ralphtheninja
источник
3
Это было очень быстро :) Вы можете добавить, что он должен использовать git://URL со страницы репозитория GitHub другого человека вместо //path/to/coworkers/repo.git. (Описывая это было то , что сделал мой ответ слишком медленно;))
Марк Longair
Круто :) А если я захочу внести свои изменения в эту ветку, я должен создать вторую локальную ветку "bar" из "foo" и работать там, а не прямо на моем "foo"?
Колин О'Делл
Или это безопасно работать прямо в моем "foo" и позже вытащить / объединить его изменения? Какова лучшая практика здесь?
Колин О'Делл
1
Отлично, это именно то, что я искал :) Спасибо за вашу помощь !!
Колин О'Делл
1
Хороший ответ за 3 минуты!
Tieme
103

Нет, вам не нужно добавлять их в качестве удаленного. Это было бы громоздко и каждый раз было бы больно.

Захватив их коммиты:

git fetch git@github.com:theirusername/reponame.git theirbranch:ournameforbranch

Это создает локальную ветвь с именем, ournameforbranchкоторая точно такая же, как и theirbranchдля них. Для примера вопроса последний аргумент будет foo:foo.

:ournameforbranchЧасть примечания может быть в дальнейшем удалена, если придумывать имя, которое не конфликтует с одной из ваших собственных ветвей, утомительно. В этом случае FETCH_HEADдоступная ссылка доступна. Вы можете git log FETCH_HEADувидеть их коммиты, а затем сделать что-то вроде cherry-pickedвишни выбрать их коммиты.

Оттолкнув их назад:

Часто вы хотите починить что-то их и отодвинуть это назад. Это тоже возможно:

git fetch git@github.com:theirusername/reponame.git theirbranch
git checkout FETCH_HEAD

# fix fix fix

git push git@github.com:theirusername/reponame.git HEAD:theirbranch

Если работа в отдельном состоянии вас беспокоит, непременно создайте ветку с помощью :ournameforbranchи замените FETCH_HEADи HEADвыше на ournameforbranch.

antak
источник
2
Спасибо за это, другой ответ не работает, если у вас и у другого человека есть ветви с одинаковыми именами (например, masterветка по умолчанию )
Задание
2
Стоит отметить, что этот метод не будет работать, если у вас нет таких вещей, как ключ SSH, связанный с вашей учетной записью github, см. Stackoverflow.com/questions/12940626
Przemek D
вам не нужно быть добавленным в качестве соавтора, чтобы вы могли подтолкнуть их репо?
Мед
@ Мед Конечно! Pushing предполагает, что у вас есть необходимые разрешения на удаленном конце для push. Выборка также предполагает, что путь доступен.
Антак
Если вы работаете git branch -m newbranchв этом отключенном состоянии, git потеряет рассудок и начнет говорить, что ваш репо больше не действителен. git initпохоже, это исправляет и возвращает вас в более или менее прежнее состояние с веткой с именем "newbranch".
Ян Хиксон
14

Если ответ антака:

git fetch git@github.com:<THEIR USERNAME>/<REPO>.git <THEIR BRANCH>:<OUR NAME FOR BRANCH> 

дает тебе:

Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Затем (следуя совету Przemek D) использовать

git fetch https://github.com/<THEIR USERNAME>/<REPO>.git <THEIR BRANCH>:<OUR NAME FOR BRANCH>
Питер
источник
6

Ниже приведено хорошее целесообразное решение, которое работает с GitHub для проверки ветки PR с ветки другого пользователя. Вам нужно знать идентификатор запроса на удаление (который отображается в GitHub вместе с заголовком PR).

Пример:

Исправление вашего небезопасного кода # 8
Алиса хочет объединить 1 коммит your_repo:masterсher_repo:branch

git checkout -b <branch>
git pull origin pull/8/head

Замените ваш пульт, если отличается от origin.
Замените 8на правильный ID запроса на получение.

Subfuzion
источник
2
Это требует больше голосов. работает безупречно и избегает ошибки «Неустранимый: Не удалось найти удаленный реф», которую я получаю с ответом, получившим наибольшее количество голосов. Спасибо!
Майкл Ромрелл
2 строки простого кода. Спасибо, что поделились этим! Единственное, что слаще, - это легко объединять обновления в их запрос на извлечение.
Klewis
4

GitHub имеет новую опцию относительно предыдущих ответов, просто скопируйте / вставьте командные строки из PR:

  1. Прокрутите вниз до пиара, чтобы увидеть кнопку MergeилиSquash and merge
  2. Нажмите на ссылку справа: view command line instructions
  3. Нажмите значок «Копировать» справа от шага 1
  4. Вставьте команды в свой терминал
Роберт Монфера
источник
2

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

git remote add protected_repo https://github.com/theirusername/their_repo.git
git fetch protected_repo 
git checkout --no-track protected_repo/foo

Теперь у вас есть локальная копия foo, без связанного с ней апстрима. Вы можете зафиксировать изменения в нем (или нет), а затем отправить свой файл в свое удаленное хранилище.

git push --set-upstream origin foo

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

git checkout foo 
git fetch protected_repo
git merge protected_repo/foo
Дж Смит
источник