Отправить запрос на GitHub только для последнего коммита

280

Я разработал проект на GitHub и успешно вносил изменения в мой локальный мастер и подталкивал к началу на GitHub. Я хочу отправить запрос на удаление, но хочу включить только последний коммит. Пользовательский интерфейс запроса на загрузку на github.com показывает последние 9 коммитов, и я не знаю, как это отфильтровать.

Я пытался понять, если я должен создать новую локальную ветку, проверить это и как-то сбросить или перебазировать в апстрим? Затем примените мой последний коммит от моего мастера по id к новой локальной ветке и используйте это для запроса на получение?

Я пытаюсь получить правильные концепции и определить правильные командные строки, чтобы сделать то, что мне нужно.

Кевин Хакансон
источник
А что произойдет, если вы сделаете пул-запрос со всеми другими коммитами? Я думал, что git достаточно умен, чтобы игнорировать (или передавать) коммиты, которые он уже вытащил?
Джаярджо
3
Предположительно, вышестоящий поток еще не принял или не хочет промежуточных коммитов.
Майкл Скотт Катберт
@jayarjo Я, например, сделал другие изменения, которые я не хочу отправлять в апстрим. Например, изменения в git игнорируют основной репозиторий. Нет ничего проще с мерзавцем.
Мартин
Связанный: некоторые хорошие подробности о том, как запросы извлечения различаются в Git (программное обеспечение) и GitHub (веб-сервис)
RBT

Ответы:

302

Вам нужно создать новую ветку и выбрать те коммиты, которые вы хотите добавить в нее.

Примечание: они могут понадобиться перед командами checkout / cherry-pick

git remote add upstream <git repository>

git remote update

git checkout -b <new-branch-name> upstream/master

git cherry-pick <SHA hash of commit>

git push origin <new-branch-name>

После этого вы увидите <new-branch-name>ветку на github, переключитесь на нее и сможете отправить запрос на получение с нужными вам изменениями.

Кевин Хакансон
источник
32
Мне также нужно git remote add upstream <git repository>и git remote updateдо запуска git checkout -b upstream upstream / master.
Plajjimbo
6
Это работает, но это не то, как вы должны это делать, потому что теперь ваша ветка upstream и upstream / master различны и всегда будут отличаться, если объединение вашего запроса извлечения не является первым делом, которое делает upstream. По этой причине вы должны предпочесть делать stackoverflow.com/a/5256304/1904815 .
JonnyJD
2
Для уточнения: это не техническая проблема, а логическая. Если вы хотите что-то сделать с апстримом (например, слияние оттуда), вам нужно добавить ветку «реальный апстрим» или сбросить апстрим (не оставляя локальной ветки для вашего запроса на получение дополнительных изменений).
JonnyJD
15
С какой стати мне нужна дополнительная ветка, только для того, чтобы создать пиар для одной измененной строки кода ?! Кто-нибудь в github обдумал это?
CodeManX
2
@JonHanna Нет ... зачем вообще объединять ветки? Почему вы не можете просто объединить коммит?
Кевин Крумвиде
57

Создайте новую ветку, начиная с самого последнего коммита, который также находится в исходном репозитории:

git branch new-branch origin/master
git checkout new-branch

Затем используйте git cherry-pickдля получения единственного коммита, для которого вы хотите запрос на получение. Если вызывается ветка с этим коммитом, featureа нужный коммит является последним коммитом в этой ветке, это будет

git cherry-pick feature

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

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

Ларс Нощинский
источник
Я получаю это сообщение после вишни. ничего не добавлено для фиксации, но есть неотслеживаемые файлы (используйте «git add» для отслеживания). Все в моем мастере, но мне нужно сделать свою ветку от восходящего потока.
Кевин Хакансон
5
Если featureон уже зафиксирован origin/master, во время ничего не происходит cherry-pick. Новая ветвь должна быть от upstream/master(т.е. ответ Кевина Хакансона)
ооо
26

Я оказался в ситуации, когда я разветвился и хотел отправить запрос на извлечение обратно в исходный проект.

Я имел:

  • orignal_project
  • forked_project (создан из оригинального проекта в SHA: 9685770)
  • my_fork (создан из разветвленного проекта в SHA: 207e29b)
  • коммит в моем форке (SHA: b67627b), который я хотел отправить обратно в исходный проект

Для этого я:

  1. создал новую ветку от SHA, где был разветвлен оригинальный проект
  2. вытащил все из оригинального проекта
  3. Вишня выбрала коммит, который я хотел отправить как запрос на извлечение
  4. подтолкнул все это к GitHub

Команды git были что-то вроде:

  1. git branch my-feature-request 9685770
  2. git checkout my-feature-request
  3. git pull https://github.com/original_project/original_project.git
  4. мерзавец вишня кирка b67627b
  5. git push origin my-feature-request

Затем я выбрал my-feature-request в качестве ветви для моего pull-запроса к исходному проекту.

Джон Нэгл
источник
6

Это почти сработало для меня:

git checkout -b upstream upstream/master

git cherry-pick <SHA hash of commit>

git push origin upstream

Единственная разница была в следующем:

git push origin upstream:upstream

Мне нужно было изменить эту последнюю строку, чтобы git push сделал ветвь вверх по течению в моем репозитории GitHub, чтобы я мог сделать PR из этого.

hi_tech_lowlife
источник
5

Я уже сделал коммит, который хотел бы иметь возможность изолировать как запрос на возврат к текущей ветке.

Итак, я проверил новую ветку

git checkout -b isolated-pull

И вот здесь мое решение отличается от решения @Kevin Hakanson , так как мне нужно сбросить эту ветку на то место в истории, от которого я хочу перейти

git reset --hard [sha-to-diff-by]

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

git cherry-pick [my-isolated-commit-sha]

Наконец, подтолкни его к пульту

git push origin isolated-pull

И вытащить запрос DAT Ши.

irbanana
источник
1

Решение создать новую (временную) ветвь cherry-pick и создать запрос на извлечение для этой ветки меня не удовлетворило. Я не хотел менять свой репозиторий, чтобы сделать доступным набор коммитов, поэтому я предложил следующую альтернативу:

Сначала создайте файлы патчей для всех коммитов:

git format-patch -1 <sha>

Если коммит интересов окажется последним, который вы можете использовать HEADвместо этого <sha>.

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

git branch new-branch <master or some older commit where the fork diverged>
git checkout new-branch

git am < <the patch>
...

git checkout master
git merge new-branch

Наконец, это должно выглядеть так же, как если бы временная ветвь была объединена по запросу извлечения, но без этой дополнительной ветки в репозитории fork.

Йоханнес Джендерси
источник
0

Основываясь на ответе @ kevin-hakanson, я написал этот небольшой сценарий bash, чтобы облегчить этот процесс. Он добавит репозиторий в восходящем направлении, если он еще не существует (запрашивая у вас URL), а затем запросит имя новой создаваемой ветви и тег / SHA для фиксации вишни, выбранной для этой ветви. Он проверяет, в какой ветке или коммите вы находитесь, а затем сохраняет все изменения, чтобы вы могли проверить новую ветку. Стратегия слияния сохраняет изменения от вишневого коммита. После нажатия на новую ветку origin(предполагается, что это имя вашего удаленного репо), ветка или фиксация, на которой вы были до этого, снова извлекается, и ваши предыдущие изменения извлекаются из тайника.

if ! git remote | grep -q upstream; then
    read -p "Upstream git repo URL: " upstream
    git remote add upstream $upstream
    git remote update
fi

read -p "Feature branch name: " feature_branch
# note: giving "master" is the same as giving the SHA it points to
read -p "SHA of commit to put on branch: " sha

current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" == "HEAD" ]; then
    # detached HEAD; just get the commit SHA
    current_branch=$(git rev-parse --short HEAD)
fi
git stash
git checkout -b $feature_branch upstream/master
git cherry-pick --strategy=recursive -X theirs $sha
git push origin $feature_branch
git checkout $current_branch
git stash pop

(Это сработало для меня в нескольких простых тестах, но я не программист bash или git-эксперт, поэтому дайте мне знать, если есть пропущенные мной случаи, которые можно было бы автоматизировать лучше!)

Натан
источник