###序章

オープンソースプロジェクトに貢献することは、自分のようなエンドユーザーにとってソフトウェアをより良くするために取り組むときにやりがいのある経験です。 プルリクエストを送信すると、プロジェクトに貢献するプロセスでは、承認前にコードのリベースとリワークが必要になり、その後にブランチの一般的なクリーンアップが必要になる場合があります。

このチュートリアルでは、プルリクエストをオープンソースソフトウェアプロジェクトに送信した後に実行する必要のある次の手順について説明します。

##前提条件

このチュートリアルでは、プルリクエストを作成した後に実行する手順について説明します。そのため、Gitが既にインストールされており、プルリクエストを作成したか、作成を検討している必要があります。

2020年11月の時点で、GitHubはパスワードベースの認証を削除しました。 このため、コマンドラインからGitHubリポジトリにアクセスするには、個人アクセストークンを作成するか、SSH公開鍵情報を追加する必要があります。

オープンソースプロジェクトへの貢献について詳しくは、この紹介をご覧ください。 プルリクエストの作成については、「GitHubでプルリクエストを作成する方法」をご覧ください。

##コードのリベースとコメントのクリーンアップ

オープンソースに貢献している間、ブランチまたはプルリクエストとアップストリームコードの間に競合があることに気付くかもしれません。 シェルで次のようなエラーが発生する場合があります。

Output
CONFLICT (content): Merge conflict in your-file.py Automatic merge failed; fix conflicts and then commit the result.

または、GitHubのWebサイトからのプルリクエストで次のようになります。

GitHub pull request conflicts

これは、メンテナがしばらくの間プルリクエストに応答しない場合、または多くの人が一度にプロジェクトに貢献している場合に発生する可能性があります。 これが発生してもプルリクエストをマージしたい場合は、競合を解決してコードをリベースする必要があります。

rebase を使用すると、ベースとなるコミットを変更することで、ブランチを移動できます。 このようにして、コードをリベースして、メインブランチの最近のコミットに基づいてコードを作成できます。 リベースは慎重に行う必要があり、プロセス全体を通じて適切なコミットと適切なブランチで作業していることを確認する必要があります。 エラーが発生した場合に備えて、git reflogコマンドの使用についても説明します。

プルリクエストチュートリアルで行ったように、コードディレクトリに移動します。

  1. cd repository

次に、git checkoutコマンドを使用してブランチに移動し、正しいブランチにいることを確認します。

  1. git checkout new-branch

次に、git fetchを実行して、コードの最新のアップストリームバージョンを取得します。

  1. git fetch origin

プロジェクトのアップストリームバージョンを取得したら、コミットメッセージをつぶすか言い換えて、プロジェクトメンテナが理解しやすいように、コメントをクリーンアップできます。 小さなコミットをあまり行わなかった場合、これは必要ないかもしれません。

このプロセスを開始するには、インタラクティブなリベースを実行します。 インタラクティブリベースを使用して、以前のコミットメッセージを編集したり、複数のコミットを1つに結合したり、不要になったコミットを削除または元に戻したりできます。 これを行うには、数値またはブランチのベースを参照する文字列のいずれかで行ったコミットを参照できる必要があります。

行ったコミットの数を確認するには、次のコマンドを使用して、プロジェクトに対して行われたコミットの総数を調べることができます。

  1. git log

これにより、次のような出力が提供されます。

Output
commit 46f196203a16b448bf86e0473246eda1d46d1273 Author: username-2 <email-2> Date: Mon Dec 14 07:32:45 2015 -0400 Commit details commit 66e506853b0366c87f4834bb6b39d941cd034fe3 Author: username1 <email-1> Date: Fri Nov 27 20:24:45 2015 -0500 Commit details

ログには、特定のプロジェクトのリポジトリに対して行われたすべてのコミットが表示されるため、他の人が行ったコミットと一緒にコミットが一覧表示されます。 複数の作成者によるコミットの広範な履歴があるプロジェクトの場合、コマンドで作成者として自分自身を指定することをお勧めします。

  1. git log --author=your-username

このパラメーターを指定することにより、行ったコミットをカウントできるようになります。 複数のブランチで作業している場合は、コマンドの最後に--branches[=<branch>]を追加して、ブランチごとに制限することができます。

これで、リベースするブランチで行ったコミットの数がわかっている場合は、次のようにgit rebaseコマンドを実行できます。

  1. git rebase -i HEAD~x

ここで、-iはインタラクティブなリベースを指し、HEADはメインブランチからの最新のコミットを指します。 xは、最初にブランチをフェッチしてからブランチに対して行ったコミットの数になります。

ただし、ブランチで行ったコミットの数がわからない場合は、次のコマンドを実行して、ブランチのベースであるコミットを見つける必要があります。

  1. git merge-base new-branch main

このコマンドは、コミットハッシュと呼ばれる長い文字列を返します。これは次のようになります。

Output
66e506853b0366c87f4834bb6b39d341cd094fe9

このコミットハッシュを使用して、git rebaseコマンドに渡します。

git rebase -i 66e506853b0366c87f4834bb6b39d341cd094fe9

上記のいずれのコマンドでも、コマンドラインテキストエディタが開き、ブランチ内のすべてのコミットのリストを含むファイルが表示されます。これで、コミットを破棄するか、言い換えるかを選択できます。

###スカッシュコミット

コミットメッセージを押しつぶすときは、いくつかの小さなコミットを1つの大きなコミットに押しつぶすか結合します。

各コミットの前に「pick」という単語が表示されるため、2つのコミットがある場合、ファイルは次のようになります。

GNU nano 2.0.6ファイル:… username / repository / .git / rebase-merge / git-rebase-todo
pick a1f29a6 Adding a new feature
pick 79c0e80 Here is another new feature

# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

ここで、最初の行を除くファイルの各行について、「pick」という単語を「squash」という単語に置き換えて、コミットを組み合わせる必要があります。

GNU nano 2.0.6ファイル:… username / repository / .git / rebase-merge / git-rebase-todo
pick a1f29a6 Adding a new feature
squash 79c0e80 Here is another new feature

この時点で、ファイルを保存して閉じることができます。これにより、すべてのコミットのすべてのコミットメッセージを組み合わせた新しいファイルが開きます。 必要に応じてコミットメッセージを書き直してから、ファイルを保存して閉じることができます。

ファイルを閉じると、フィードバックが届きます。

Output
Successfully rebased and updated refs/heads/new-branch.

これで、すべてのコミットをまとめて1つにまとめました。

###Rewordコミット

コミットメッセージの言い換えは、タイプミスに気付いた場合、または各コミットに並列言語を使用していないことに気付いた場合に最適です。

git rebase -iコマンドを使用して上記のようにインタラクティブなリベースを実行すると、次のようなファイルが開きます。

GNU nano 2.0.6ファイル:… username / repository / .git / rebase-merge / git-rebase-todo
pick a1f29a6 Adding a new feature
pick 79c0e80 Here is another new feature

# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

ここで、言い換えたいコミットごとに、「pick」という単語を「reword」に置き換えます。

GNU nano 2.0.6ファイル:… username / repository / .git / rebase-merge / git-rebase-todo
pick a1f29a6 Adding a new feature
reword 79c0e80 Adding a second new feature

# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

ファイルを保存して閉じると、ターミナルエディタに新しいテキストファイルが表示され、コミットメッセージの変更された文言が示されます。 ファイルを再度編集する場合は、ファイルを保存して閉じる前に編集できます。 これを行うことで、コミットメッセージが有用で統一されていることを確認できます。

###リベースを完了する

実行しているコミットの数と関連するコミットメッセージに満足したら、プロジェクトのアップストリームコードの最新バージョンに加えてブランチのリベースを完了する必要があります。 これを行うには、リポジトリのディレクトリから次のコマンドを実行する必要があります。

  1. git rebase origin/main

この時点で、Gitはコミットを最新バージョンのmainに再生し始めます。 これが発生している間に競合が発生した場合、Gitは一時停止して、続行する前に競合を解決するように求めます。 解決するものがない場合、出力には次のように表示されます。

Output
Current branch new-branch is up to date.

競合を修正したら、次を実行します。

  1. git rebase --continue

このコマンドは、コミットの再生を続行できることをGitに示します。

以前にsquashコマンドを使用してコミットを組み合わせた場合、競合を解決する必要があるのは1回だけです。

###強制プッシュでプルリクエストを更新

リベースを実行すると、ブランチの履歴が変更され、ダイレクトパスが変更されたため、git pushコマンドを使用できなくなります。

代わりに、--forceまたは-fフラグを使用して変更を強制的にプッシュし、プッシュしているものを完全に認識していることをGitに通知する必要があります。

まず、push.defaultsimpleであることを確認しましょう。これは、Git2.0以降のデフォルトです。

  1. git config --global push.default simple

この時点で、作業中のブランチをチェックして、正しいブランチにいることを確認する必要があります。

  1. git checkout new-branch
Output
Already on 'new-branch' . . .

これで、フォースプッシュを実行できます。

  1. git push -f

これで、これがforced updateであるというメッセージとともに更新のフィードバックを受け取るはずです。 これでプルリクエストが更新されました。

###失われたコミットの回復

ある時点で、本当に大きなプロジェクトに統合したいコミットを破棄した場合、Gitを使用して、誤って破棄した可能性のあるコミットを復元できるはずです。

git reflogコマンドを使用して、欠落しているコミットを見つけ、そのコミットから新しいブランチを作成します。

Reflog は、 reference logs の略で、ローカルリポジトリ内でブランチのヒントやその他の参照が最後に更新された日時を記録します。

作業しているコードリポジトリのローカルディレクトリから、次のコマンドを実行します。

  1. git reflog

このコマンドを実行すると、次のような出力が表示されます。

Output
46f1962 HEAD@{0}: checkout: moving from branch-1 to new-branch 9370d03 HEAD@{1}: commit: code cleanups a1f29a6 HEAD@{2}: commit: brand new feature 38f2fc2 HEAD@{3}: commit: remove testing methods . . .

コミットメッセージは、どのコミットが残されたものであるかを通知し、関連する文字列は、ターミナルウィンドウの左側にあるHEAD@{x}情報の前に表示されます。

これで、その情報を取得して、関連するコミットから新しいブランチを作成できます。

git checkout -b new-new-branch a1f29a6

上記の例では、上記の3番目のコミットから新しいブランチを作成しました。これは、文字列a1f29a6で表される「まったく新しい機能」をロールアウトしたものです。

ここから何をする必要があるかに応じて、プルリクエストに関するこのチュートリアルでブランチを設定する手順に従うか、現在のチュートリアルトップに戻って作業することができます新しいブランチのリベースを通じて。

:最近git gcコマンドを実行して不要なファイルをクリーンアップし、ローカルリポジトリを最適化した場合、失われたコミットを復元できない可能性があります。

##コードレビューで何を期待するか

プルリクエストを送信すると、より大きなプロジェクトと対話します。 プルリクエストを送信することは、あなた自身がより大きなプロジェクトについて話し、従事しているのと同じように、他の人にあなたの仕事について話すように勧めることです。 会話を成功させるには、コミットメッセージを介してプルリクエストを行う理由を伝えることができることが重要です。そのため、できるだけ正確かつ明確にすることが最善です。

プロジェクトによっては、プルリクエストのレビューに時間がかかり、詳細になる場合があります。 このプロセスは学習体験であり、コードを改善し、プルリクエストをソフトウェアプロジェクトのニーズに合わせて改善するための良い方法と考えるのが最善です。 レビューでは、メンテナのアドバイスと指示を通じて自分で変更を加えることができるはずです。

プルリクエストは、レビュー担当者からのメモと、一緒に行った更新やディスカッションのログを保持します。 プルリクエストが受け入れられる前に、このプロセス全体でいくつかの追加のコミットを行う必要がある場合があります。 これは完全に正常であり、チームの一員として改訂に取り組む良い機会を提供します。

プルリクエストは引き続きGitを介して維持され、同じブランチにコミットを追加してフォークにプッシュし続ける限り、プロセス全体で自動更新されます。

同僚によるレビューのためにコードをより広い世界に公開していますが、レビューが個人的なものになっていると感じさせてはいけません。関連するCONTRIBUTION.mdファイルまたは行動規範を必ず読んでください。 コミットがプロジェクトで指定されたガイドラインに沿っていることを確認することが重要ですが、不快に感じ始めた場合、作業中のプロジェクトは貢献に値しない可能性があります。 オープンソースコミュニティには多くの歓迎の場があり、コードが批判的な目で見られることを期待できますが、受け取るフィードバックはすべて専門的かつ丁寧でなければなりません。

##プルリクエストの承認とブランチの削除

プルリクエストが受け入れられた場合、オープンソースソフトウェアプロジェクトへの貢献に成功しています。

この時点で、ローカルリポジトリを介してフォークに加えた変更をプルする必要があります。 これは、フォーク同期するプロセスを実行したときにすでに行ったことです。 これは、ターミナルウィンドウで次のコマンドを使用して実行できます。

  1. git checkout main
  2. git pull --rebase origin main
  3. git push -f origin main

ここで、両方の場所で作成したブランチが不要になったため、それらを削除して、ローカルブランチとリモートブランチの両方をクリーンアップする必要があります。 まず、ローカルブランチを削除しましょう。

  1. git branch -d new-branch

git branchコマンドに追加された-dフラグは、コマンドに渡したブランチを削除します。 上記の例では、new-branchと呼ばれています。

次に、リモートブランチを削除します。

  1. git push origin --delete new-branch

ブランチが削除されたので、リポジトリがクリーンアップされ、変更がメインリポジトリに保存されます。 プルリクエストで行った変更はメインリポジトリの一部になっているため、パブリックリリースをダウンロードしている平均的なエンドユーザーは変更できない可能性があることに注意してください。 一般的に、ソフトウェアメンテナは、いくつかの新機能と修正を1つの公開リリースにまとめます。

##結論

このチュートリアルでは、プルリクエストをオープンソースソフトウェアリポジトリに送信した後に完了する必要のある次の手順のいくつかについて説明しました。

オープンソースプロジェクトに貢献すること、そしてアクティブなオープンソース開発者になることは、多くの場合、やりがいのある経験です。 頻繁に使用するソフトウェアに定期的に貢献することは、そのソフトウェアがユーザーのコミュニティにとって価値があり有用であることを保証するのに役立ちます。