GNU/Linux >> Linux の 問題 >  >> Linux

差分とパッチの概要

分散開発モデルを使用して大規模なコードベースで作業したことがある場合は、「スーがパッチを送信したばかり」や「ラジブが差分をチェックしている」などと言われるのを聞いたことがあるでしょう。たぶん、それらの用語はあなたにとって新しいものであり、あなたはそれらが何を意味するのか疑問に思いました。 Apache WebサーバーからLinuxカーネルまでの大規模プロジェクトの主な開発モデルは、その存続期間を通じて「パッチベース」の開発プロジェクトであったため、ここではオープンソースが影響を及ぼしました。実際、Apacheの名前は、元のNCSA HTTPdサーバーのソースコードに対して収集および照合された一連のパッチに由来していることをご存知ですか?

これは民間伝承だと思われるかもしれませんが、Apache Webサイトの初期のキャプチャでは、この名前はこの元の「パッチ」コレクションに由来していると主張しています。したがって、 APA t CH yサーバー。その後Apacheに簡略化されました。

しかし、十分な歴史の雑学。これらのパッチは正確には何ですか および差分 開発者が話していることは?

まず、この記事のために、これら2つの用語が1つの同じものを参照していると仮定しましょう。 「diff」は単に「difference」の略です。同じ名前のUnixユーティリティは、1つ以上のファイルの違いを明らかにします。以下でdiffユーティリティの例を見ていきます。

「パッチ」とは、Unixのdiffユーティリティを使用してソースコードツリーに適用できるファイル間の特定の相違点のコレクションを指します。したがって、diffツールを使用してdiff(またはパッチ)を作成し、パッチツールを使用して同じソースコードのパッチが適用されていないバージョンに適用できます。余談ですが(そして、これ以上の歴史の雑学のルールを破る)、「パッチ」という言葉は、パンチカードがコンピュータのプロセッサによって実行されるプログラムを表していた初期のコンピューティング時代にソフトウェアを変更するためにパンチカードの穴を物理的に覆うことに由来します。ソフトウェアパッチについて説明しているこのウィキペディアのページにある以下の画像は、この元の「パッチ適用」の概念を示しています。

パッチと差分の基本を理解したところで、ソフトウェア開発者がこれらのツールをどのように使用するかを見ていきましょう。 GitやSubversionなどのソースコード管理システムを使用したことがない場合は、重要なソフトウェアプロジェクトのほとんどを開発するための準備を整えます。ソフトウェアプロジェクトの存続期間をタイムラインに沿った一連のアクションと考えると、ソースコードファイルへの機能の追加やバグの修正など、ソフトウェアへの変更がさまざまな時点で表示されることを視覚化できます。タイムライン。各個別のポイントは、その時点でのすべてのソースコードファイルの状態を表します。これらの変更点を「コミット」と呼び、今日最も人気のあるソースコード管理ツールであるGitが使用しているのと同じ命名法を使用します。特定のコミットの前後、または多くのコミット間のソースコードの違いを確認したい場合は、ツールを使用して差分または違いを表示できます。

これと同じソースコード管理ツールであるGitを使用してソフトウェアを開発している場合は、ローカルシステムに変更を加えて、他のユーザーが自分のツリーにコミットとして追加できるようにすることができます。他の人にローカルの変更を提供する1つの方法は、ローカルツリーの変更の差分を作成し、同じソースコードで作業している他の人にこの「パッチ」を送信することです。これにより、他のユーザーが自分のツリーにパッチを適用し、変更が適用されたソースコードツリーを確認できます。

Linux、Git、GitHub

パッチファイルを共有するこのモデルは、今日提案されている変更に関してLinuxカーネルコミュニティがどのように機能するかを示しています。人気のあるLinuxカーネルメーリングリスト(LKMLが主要なものですが、他にはlinux-containers、fs-devel、Netdevなど)のアーカイブを見ると、多くの開発者がパッチを投稿していることがわかります。他の人にレビュー、テスト、そしておそらくある時点で公式のLinuxカーネルGitツリーを導入してもらいたい。 Linus Torvaldsによって作成されたソースコード管理システムであるGitについて詳しく説明することはこの記事の範囲外ですが、Gitによってこの分散開発モデルが有効になり、パッチをメインリポジトリとは別に使用できるようになります。さまざまなツリーに引き込み、特定の開発フローに従います。

先に進む前に、パッチと差分が関連する最も人気のあるサービスであるGitHubを無視することはできません。その名前から、GitHubはGitに基づいていると推測できますが、分散型オープンソースプロジェクト開発用のGitツールに関するWebベースおよびAPIベースのワークフローを提供します。 GitHubでパッチを共有する主な方法の1つは、Linuxカーネルのようにメールではなく、プルリクエストを作成することです。 。ソースコードツリーの独自のコピーに変更をコミットする場合、そのソフトウェアプロジェクトの一般的に共有されるリポジトリに対してプルリクエストを作成することにより、それらの変更を共有できます。 GitHubは、Kubernetes、Docker、Container Network Interface(CNI)、Istioなど、今日多くのアクティブで人気のあるオープンソースプロジェクトで使用されています。 GitHubの世界では、ユーザーはWebベースのインターフェースを使用して、プルリクエストを構成する差分またはパッチを確認する傾向がありますが、未加工のパッチファイルにアクセスして、パッチユーティリティを使用してコマンドラインで使用することもできます。

>

ビジネスに取り掛かる

パッチと差分、およびそれらが人気のあるオープンソースコミュニティやツールでどのように使用されるかについて説明したので、いくつかの例を見てみましょう。

最初の例には、ソースツリーの2つのコピーが含まれており、1つには、diffユーティリティを使用して視覚化する変更があります。この例では、「統一された」差分を見ていきます。これは、現代のソフトウェア開発の世界のほとんどでパッチに期待されるビューだからです。オプションと違いを生み出す方法の詳細については、diffのマニュアルページを確認してください。元のソースコードはsources-origにあり、2番目の変更されたコードベースはsources-fixedという名前のディレクトリにあります。端末で統一された差分形式で違いを表示するには、次のコマンドを使用します。

$ diff -Naur sources-orig/ sources-fixed/

...次に、次のdiffコマンド出力が表示されます:

diff -Naur sources-orig/officespace/interest.go sources-fixed/officespace/interest.go
--- sources-orig/officespace/interest.go        2018-08-10 16:39:11.000000000 -0400
+++ sources-fixed/officespace/interest.go       2018-08-10 16:39:40.000000000 -0400
@@ -11,15 +11,13 @@
   InterestRate float64
 }

+// compute the rounded interest for a transaction
 func computeInterest(acct *Account, t Transaction) float64 {

   interest := t.Amount * t.InterestRate
   roundedInterest := math.Floor(interest*100) / 100.0
   remainingInterest := interest - roundedInterest

-  // a little extra..
-  remainingInterest *= 1000
-
   // Save the remaining interest into an account we control:
   acct.Balance = acct.Balance + remainingInterest

diffコマンド出力の最初の数行は、いくつかの説明を使用できます。3つの--- 記号は元のファイル名を示します。元のファイルには存在するが、比較された新しいファイルには存在しない行には、単一の-というプレフィックスが付けられます。 この行はソースから「差し引かれた」ことに注意してください。 +++ 記号は反対を示しま​​す。比較された新しいファイルとこのファイルで見つかった追加は、単一の+でマークされます。 新しいバージョンのファイルに追加されたことを示す記号。各「ハンク」(@@のプレフィックスが付いたセクション 差分パッチファイルの)には、パッチツール(または他のプロセッサ)がこの変更を適用する場所を知るのに役立つコンテキスト行番号があります。 「OfficeSpace」の映画参照関数から、ソフトウェア開発者の1人の欲望を修正したことがわかります。この関数は、関数へのコメントとともに、丸められた利息の計算に少し追加しました。 。

他の誰かにこのツリーからの変更をテストしてもらいたい場合は、diffからのこの出力をパッチファイルに保存できます:

$ diff -Naur sources-orig/ sources-fixed/ >myfixes.patch

これで、パッチファイルmyfixes.patchができました。このファイルを別の開発者と共有して、この一連の変更を適用およびテストできます。仲間の開発者は、現在の作業ディレクトリがソースコードツリーのベースにある場合、パッチツールを使用して変更を適用できます。

$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go

これで、他の開発者のソースツリーにパッチが適用され、パッチを介して適用された変更をビルドしてテストする準備が整いました。この開発者がinterest.goに個別に変更を加えた場合はどうなりますか?変更が直接競合しない限り(たとえば、同じ正確な行を変更する場合)、パッチツールは、変更をマージする場所を解決できる必要があります。例として、他のいくつかの変更を含むinterest.goファイルがで使用されます。次のパッチの実行例:

$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
Hunk #1 succeeded at 26 (offset 15 lines).

この場合、パッチは、変更がファイル内の元の場所に適用されなかったが、15行オフセットされたことを警告します。ファイルを大幅に変更した場合、パッチは変更がどこに収まるかを見つけるのをあきらめる可能性がありますが、一致する「あいまいさ」(この記事の範囲を超えています)を上げるためのオプションを提供します(ドキュメントに必要な警告があります) 。

GitやGitHubを使用している場合は、おそらく差分ツールやパッチツールをスタンドアロンツールとして使用することはありません。 Gitはこの機能の多くを提供するため、他の開発者の変更をマージおよびプルして、共有ソースツリーで作業する組み込み機能を使用できます。同様の機能の1つは、git diffを使用して、ローカルツリーまたは任意の2つの参照(コミット識別子、タグまたはブランチの名前など)間で統一されたdiff出力を提供することです。パッチが使用できるdiffコマンドの正確な形式を使用している場合は、Gitを使用していない人がgitdiff出力をファイルにパイプするだけで役立つパッチファイルを作成することもできます。もちろん、GitHubはこれらの機能をWebベースのユーザーインターフェイスに取り入れているため、プルリクエストでファイルの変更を表示できます。このビューでは、これが事実上Webブラウザーの統一された差分ビューであり、GitHubを使用してこれらの変更を未加工のパッチファイルとしてダウンロードできることに気付くでしょう。

概要

差分とパッチ、およびそれらと相互作用する一般的なUnix/Linuxコマンドラインツールについて学習しました。 Linuxカーネルのように、パッチファイルベースの開発方法をまだ使用しているプロジェクトの開発者でない限り、これらの機能は主にGitなどのソースコード管理システムを介して使用されます。ただし、GitHubなどの高レベルのツールを通じて、多くの開発者が日常的に使用している機能の背景と基盤を理解しておくと役立ちます。そして、誰が知っているのでしょうか。Linuxの世界で、メーリングリストのパッチを操作する必要があるときに便利になるかもしれません。


Linux
  1. Netstatのソースコード?

  2. Linux コマンドのソース コードを入手する

  3. Linux でソース コードからソフトウェアをコンパイルしてインストールする方法

  1. トップ5のソースコードリポジトリ

  2. MIXXX –美しく、無料の、オープンソースのDJソフトウェア

  3. C コードをコンパイルし、Linux で Swift に公開する

  1. C++ で C 関数を呼び出す方法、C で C++ 関数を呼び出す方法 (C と C++ の混合)

  2. malloc と free のコード

  3. Linux CFS スケジューラ コードはどこにありますか?