Envie uma solicitação pull no GitHub para apenas a confirmação mais recente


280

Eu criei um projeto no github e estou fazendo alterações no meu mestre local com sucesso e avançando para a origem no github. Quero enviar uma solicitação de recebimento, mas quero incluir apenas a última confirmação. A interface do usuário de solicitação de recebimento no github.com mostra os últimos 9 confirmados e não sei como filtrar isso.

Eu estava tentando entender se eu deveria criar uma nova filial local, verificar isso e, de alguma forma, redefinir ou refazer a atualização para o upstream? Em seguida, aplique minha última confirmação do meu mestre por id para a nova ramificação local e use-a para a solicitação pull?

Estou tentando acertar os conceitos e descobrir as linhas de comando certas para fazer o que eu preciso.


E o que acontece se você fizer uma solicitação pull com todas as outras confirmações? Eu pensei que o git é inteligente o suficiente para ignorar (ou passar) os commits que ele já recebeu?
— Jayarjo # 29/12

3
Presumivelmente, o rio acima ainda não aceitou ou não quer que os intervenientes se comprometam.
— Michael Scott Cuthbert

@ jayarjo Por exemplo, fiz outras alterações que não quero enviar a montante. Mudanças no git ignoram o repositório principal, por exemplo. Nada fácil com o git.
— Martin

Related: Alguns bons detalhes sobre como as solicitações de pull são diferentes em Git (o software) e GitHub (o serviço web)
— RBT

Respostas:


302

Você precisa basicamente criar uma nova ramificação e escolher os commits que deseja adicionar a ela.

Nota: pode ser necessário antes dos comandos 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>

Depois, você verá uma <new-branch-name>ramificação no github, mudará para ela e poderá enviar a solicitação de recebimento com as alterações desejadas.


32
Também preciso git remote add upstream <git repository>e git remote updateantes de executar o git checkout -b upstream upstream / master.
— plainjimbo

6
Isso funciona, mas não é como você deve fazê-lo, porque agora sua ramificação upstream e upstream / master são diferentes e sempre serão diferentes se a mesclagem de sua solicitação pull não for a primeira coisa que o upstream faz. Por esse motivo, você deve preferir fazer o stackoverflow.com/a/5256304/1904815 .
— precisa saber é o seguinte

2
Para elaborar: Este não é um problema técnico, mas lógico. Quando você deseja fazer algo com o upstream (como mesclar a partir daí), é necessário adicionar uma ramificação "real-upstream" ou redefinir sua upstream (não deixando nenhuma ramificação local para sua solicitação de pull para alterações adicionais).
— precisa saber é o seguinte

15
Por que diabos eu preciso de uma ramificação extra, apenas para criar um PR para uma única linha de código alterada ?! Alguém no github pensou nisso?
— CodeManX 20/08/2015

2
@ JonHanna Não ... por que você precisa mesclar uma filial? Por que você não pode simplesmente mesclar um commit?
— Kevin Krumwiede

57

Crie uma nova ramificação a partir da confirmação mais recente, que também está no repositório de origem:

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

Em seguida, use git cherry-pickpara obter a confirmação única para a qual você deseja a solicitação de recebimento. Se o ramo com este commit for chamado featuree o commit desejado for o último commit neste branch, isso será

git cherry-pick feature

Supondo que esse patch se aplique sem conflito, você tem agora uma ramificação para a qual pode fazer sua solicitação de recebimento.

Em uma segunda etapa, agora você precisa decidir o que fazer com sua featurefilial. Se você ainda não publicou suas alterações neste ramo, o melhor procedimento é provavelmente reestruturar esse ramo em novo ramo (e remover o último commit, se isso não for feito automaticamente por git rebase).


Recebo esta mensagem após a escolha da cereja. nada adicionado ao commit, mas arquivos não rastreados estão presentes (use "git add" para rastrear). Tudo está no meu mestre, mas eu preciso fazer meu ramo a montante.
— Kevin Hakanson

5
Se o featurejá estiver confirmado origin/master, nada acontecerá durante cherry-pick. O novo ramo deve ser de upstream/master(ou seja, a resposta de Kevin Hakanson)
— ohho 31/01

26

Acabei em uma situação em que eu tinha garfado um garfo e queria enviar uma solicitação de recebimento de volta ao projeto original.

Eu tinha:

  • orignal_project
  • forked_project (criado a partir do projeto original em SHA: 9685770)
  • my_fork (criado a partir do projeto bifurcado na SHA: 207e29b)
  • um commit no meu fork (SHA: b67627b) que eu queria enviar de volta ao projeto original

Para fazer isso, eu:

  1. criou uma nova ramificação do SHA onde o projeto original foi bifurcado
  2. puxou tudo do projeto original
  3. cherry escolheu o commit que eu queria enviar como uma solicitação pull
  4. empurrou tudo para o github

Os comandos git eram algo como:

  1. ramificação git my-feature-request 9685770
  2. git checkout my-feature-request
  3. git pull https://github.com/original_project/original_project.git
  4. git cherry-pick b67627b
  5. origem git push my-feature-request

Em seguida, escolhi minha solicitação de recurso como a ramificação da minha solicitação de recebimento para o projeto original.


6

Isso quase funcionou para mim:

git checkout -b upstream upstream/master

git cherry-pick <SHA hash of commit>

git push origin upstream

A única diferença era esta:

git push origin upstream:upstream

Eu precisava alterar a última linha para que o git push fizesse a ramificação upstream no meu repositório do GitHub para que eu pudesse fazer PR a partir dele.


5

Eu já havia feito o commit que eu queria poder isolar como uma solicitação pull de volta à ramificação atual.

Então eu verifiquei uma nova filial

git checkout -b isolated-pull

E aqui é onde minha solução difere da @Kevin Hakanson , pois preciso redefinir esse ramo para o local da história em que quero diferenciar

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

E escolha o commit a partir do qual eu quero criar uma solicitação de recebimento isolada

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

Finalmente empurre-o para o controle remoto

git push origin isolated-pull

E puxe solicitação dat shi.


1

A solução para criar uma nova ramificação (temporária), escolher cereja e criar a solicitação de recebimento para essa ramificação não me satisfez. Eu não queria mudar meu repositório para disponibilizar um conjunto de confirmações, então criei a seguinte alternativa:

Primeiro, crie arquivos de correção para todos os commits de interesse:

git format-patch -1 <sha>

Se a confirmação de interesse passa a ser o último que você pode usar HEADem vez<sha> .

Agora, você pode enviar os patches para o mantenedor do repositório de origem, que pode aplicá-los:

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

Finalmente, isso deve parecer o mesmo que se uma ramificação temporária fosse mesclada por uma solicitação pull, mas sem a ramificação adicional no repositório de bifurcações.


0

Com base na resposta do @ kevin-hakanson, escrevi este pequeno script bash para facilitar esse processo. Ele adicionará o repositório upstream se ele ainda não existir (solicitando o URL) e solicitará o nome da nova ramificação a ser criada e a tag / SHA da confirmação para escolher essa ramificação. Ele verifica em qual ramificação ou confirmação você está no momento e oculta as alterações para que você possa fazer check-out da nova ramificação. A estratégia de mesclagem mantém as alterações do commit escolhido pela cereja. Depois de enviar a nova ramificação para origin(assumida como o nome do seu repositório remoto), a ramificação ou confirmação em que você esteve antes é novamente verificada e as alterações anteriores foram salvas da ocultação.

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

(Isso funcionou para mim em alguns testes simples, mas eu não sou um programador de bash ou especialista em git, então deixe-me saber se há casos que perdi que poderiam ser automatizados melhor!)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.