Gửi yêu cầu kéo trên GitHub chỉ cho cam kết mới nhất


280

Tôi đã rẽ nhánh một dự án trên github và đang thực hiện thành công các thay đổi cho chủ địa phương của mình và đẩy về nguồn gốc trên github. Tôi muốn gửi một yêu cầu kéo, nhưng chỉ muốn bao gồm các cam kết cuối cùng. Giao diện người dùng yêu cầu kéo trên github.com hiển thị 9 lần xác nhận gần nhất và tôi không biết cách lọc nó xuống.

Tôi đã cố gắng để hiểu nếu tôi nên tạo một chi nhánh địa phương mới, kiểm tra xem và bằng cách nào đó thiết lập lại hoặc rebase để ngược dòng? Sau đó áp dụng cam kết cuối cùng của tôi từ chủ của tôi bằng id cho chi nhánh địa phương mới và sử dụng cam kết đó cho yêu cầu kéo?

Tôi đang cố gắng để làm cho các khái niệm đúng và tìm ra các dòng lệnh đúng để làm những gì tôi cần.


Và điều gì xảy ra nếu bạn thực hiện một yêu cầu kéo với tất cả các cam kết khác? Tôi nghĩ git đủ thông minh để bỏ qua (hoặc vượt qua) các cam kết mà nó đã kéo vào?
jayarjo

3
Có lẽ là thượng nguồn chưa được chấp nhận hoặc không muốn, các cam kết can thiệp.
Michael Scott Cuthbert

@jayarjo Tôi lấy ví dụ về những thay đổi khác mà tôi không muốn gửi ngược dòng. Thay đổi git bỏ qua kho lưu trữ chính sẽ không cần ví dụ. Không có gì dễ dàng với git.
Martin

Liên quan: Một số chi tiết tốt về cách yêu cầu kéo khác nhau trong Git (phần mềm) và GitHub (dịch vụ web)
RBT

Câu trả lời:


302

Về cơ bản, bạn cần tạo một nhánh mới và chọn các cam kết bạn muốn thêm vào nó.

Lưu ý: bạn có thể cần những thứ này trước các lệnh thanh toán / 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>

Sau đó, bạn sẽ thấy <new-branch-name>chi nhánh trên github, chuyển sang nó và có thể gửi yêu cầu kéo với những thay đổi bạn muốn.


32
Tôi cũng cần git remote add upstream <git repository>git remote updatetrước khi chạy kiểm tra git -b ngược dòng / chủ.
plainjimbo

6
Điều này hoạt động, nhưng không phải là cách bạn phải làm, bởi vì bây giờ nhánh ngược dòng và ngược dòng / chủ của bạn khác nhau và sẽ luôn khác nhau nếu hợp nhất yêu cầu kéo của bạn không phải là điều đầu tiên ngược dòng. Vì lý do đó, bạn nên làm stackoverflow.com/a/5256304/1904815 .
JonnyJD

2
Để giải thích: Đây không phải là một vấn đề kỹ thuật, mà là một vấn đề hợp lý. Khi bạn muốn làm bất cứ điều gì với ngược dòng (như hợp nhất từ ​​đó), bạn cần thêm một nhánh "ngược dòng" hoặc đặt lại dòng ngược của bạn (không để lại chi nhánh địa phương cho yêu cầu kéo của bạn để thay đổi bổ sung).
JonnyJD

15
Tại sao tôi cần một chi nhánh phụ, chỉ để tạo PR cho một dòng mã thay đổi duy nhất?! Có ai ở github nghĩ điều này thông qua?
CodeManX

2
@JonHanna Không ... tại sao bạn phải hợp nhất một chi nhánh? Tại sao bạn không thể hợp nhất một cam kết?
Kevin Krumwiede

57

Tạo một nhánh mới bắt đầu từ cam kết mới nhất, cũng nằm trong kho lưu trữ gốc:

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

Sau đó sử dụng git cherry-pickđể có được cam kết duy nhất bạn muốn yêu cầu kéo. Nếu nhánh có cam kết này được gọi featurevà cam kết bạn muốn là cam kết mới nhất trong nhánh này, thì nó sẽ là

git cherry-pick feature

Giả sử bản vá này được áp dụng mà không có xung đột, giờ đây bạn đã có một chi nhánh để bạn có thể thực hiện yêu cầu kéo của mình.

Trong bước thứ hai, bây giờ bạn cần quyết định phải làm gì với featurechi nhánh của mình . Nếu bạn chưa công bố các thay đổi của mình trên chi nhánh này, quy trình tốt nhất có lẽ là loại bỏ chi nhánh này trên chi nhánh mới (và xóa cam kết cuối cùng, nếu việc này không được thực hiện tự động git rebase).


Tôi nhận được tin nhắn này sau khi chọn anh đào. không có gì được thêm vào cam kết nhưng hiện tại các tệp chưa được theo dõi (sử dụng "git add" để theo dõi). Tất cả mọi thứ là trong chủ của tôi, nhưng tôi cần phải làm cho chi nhánh của tôi từ thượng nguồn.
Kevin Hakanson

5
Nếu featuređã được cam kết origin/master, không có gì xảy ra trong cherry-pick. Chi nhánh mới phải từ upstream/master(tức là câu trả lời của Kevin
Hakanson

26

Tôi đã kết thúc trong một tình huống mà tôi đã rẽ nhánh ngã ba và muốn gửi yêu cầu kéo trở lại dự án ban đầu.

Tôi đã có:

  • orignal_project
  • forked_project (được tạo từ dự án ban đầu tại SHA: 9685770)
  • my_fork (được tạo từ dự án rẽ nhánh tại SHA: 207e29b)
  • một cam kết trong ngã ba của tôi (SHA: b67627b) mà tôi muốn gửi lại cho dự án ban đầu

Để làm điều này, tôi:

  1. đã tạo một chi nhánh mới từ SHA nơi dự án ban đầu được rẽ nhánh
  2. lấy tất cả từ dự án ban đầu
  3. cherry đã chọn cam kết mà tôi muốn gửi như một yêu cầu kéo
  4. đẩy tất cả lên github

Các lệnh git là một cái gì đó như:

  1. chi nhánh git my-Feature-request 9685770
  2. kiểm tra git my-Feature-request
  3. git pull https://github.com/origen_project/origen_project.git
  4. git cherry-pick b67627b
  5. git đẩy nguồn gốc yêu cầu của tôi

Sau đó, tôi chọn yêu cầu tính năng của tôi làm chi nhánh cho yêu cầu kéo của tôi đến dự án ban đầu.


6

Điều này gần như làm việc cho tôi:

git checkout -b upstream upstream/master

git cherry-pick <SHA hash of commit>

git push origin upstream

Sự khác biệt duy nhất là đây:

git push origin upstream:upstream

Tôi cần phải thay đổi dòng cuối cùng đó để git đẩy sẽ tạo ra nhánh ngược dòng trong repo GitHub của tôi để tôi có thể thực hiện PR từ nó.


5

Tôi đã thực hiện cam kết mà tôi muốn có thể cô lập như một yêu cầu kéo trở lại chi nhánh hiện tại.

Vì vậy, tôi đã kiểm tra một chi nhánh mới

git checkout -b isolated-pull

Và đây là nơi giải pháp của tôi khác với @Kevin Hakanson , vì tôi cần đặt lại chi nhánh này đến vị trí trong lịch sử mà tôi muốn khác

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

Và chọn lấy cam kết mà tôi muốn tạo một yêu cầu kéo riêng biệt

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

Cuối cùng đẩy nó lên từ xa

git push origin isolated-pull

Và kéo yêu cầu dat shi.


1

Giải pháp tạo chi nhánh mới (tạm thời), chọn cherry và tạo yêu cầu kéo cho chi nhánh đó không làm tôi hài lòng. Tôi không muốn thay đổi kho lưu trữ của mình để cung cấp một bộ xác nhận, vì vậy tôi đã đưa ra giải pháp thay thế sau:

Đầu tiên tạo tập tin vá cho tất cả các cam kết quan tâm:

git format-patch -1 <sha>

Nếu cam kết lợi ích xảy ra là lần cuối cùng bạn có thể sử dụng HEADthay thế <sha>.

Bây giờ, bạn có thể gửi các bản vá cho người bảo trì kho lưu trữ nguồn, người có thể áp dụng chúng:

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

Cuối cùng, điều này sẽ trông giống như nếu một nhánh tạm thời được hợp nhất bởi một yêu cầu kéo, nhưng không có nhánh bổ sung đó trong kho lưu trữ ngã ba.


0

Dựa trên câu trả lời của @ kevin-hakanson, tôi đã viết kịch bản bash nhỏ này để làm cho quá trình này dễ dàng hơn. Nó sẽ thêm repo ngược dòng nếu nó chưa tồn tại (nhắc bạn về URL) sau đó nhắc cả tên của nhánh mới để tạo và thẻ / SHA của cam kết chọn cherry vào nhánh đó. Nó kiểm tra chi nhánh hoặc cam kết hiện tại của bạn sau đó thực hiện bất kỳ thay đổi nào để bạn có thể kiểm tra chi nhánh mới. Chiến lược hợp nhất giữ các thay đổi từ cam kết được chọn. Sau khi đẩy chi nhánh mới sang origin(được coi là tên của repo từ xa của bạn), chi nhánh hoặc cam kết bạn đã thực hiện trước đó sẽ được kiểm tra lại và các thay đổi trước đó của bạn xuất hiện từ stash.

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

(Điều này đã làm việc cho tôi trong một vài thử nghiệm đơn giản, nhưng tôi không phải là lập trình viên bash hoặc chuyên gia git, vì vậy hãy cho tôi biết nếu có trường hợp tôi bỏ lỡ có thể được tự động hóa tốt hơn!)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.