12

を使用して3つのコミットからパッチを作成しました

git format-patch <revision_three_commits_ago>

これにより、ノートブックからメールで送信し、デスクトップコンピューター(どちらもWindowsボックス)でメールを読み取る3つのパッチファイルが作成されます。

私が今やるとき

git am --3way --ignore-space-change *.patch

パッチは適用されますが、コミットに対して同じSHA1IDを取得できません。パッチを適用したファイルを少し検索すると、デスクトップコンピュータの変更された行がで終わるLFのに対し、ノートブック(パッチを作成した場所)の変更された行はで終わることがわかりましたCR LF

だから、私の最初の考えはなしで呼び出すことでしたgit am--ignore-space-change、これは私にエラーを与えます(パッチは適用されません)。

行末(msysgit 1.7.4)の処理方法を教えてくださいgit format-patchgit am

パッチを適用する前にUNIX、本当にVIMを取得してファイル形式をからに変更する必要がありますか?DOS


編集: VIMでパッチファイルを変更することすら役に立ちません:私は考えました、set ff=dosそして:%s/^M//gそれは役立つでしょう、しかしそれはしません!

私の意見では、パッチを適用すると、パッチが作成された他のリポジトリから取得したのとまったく同じコンテンツと同じコミットハッシュが得られるはずです。私はそれについて間違って考えていますか?

4

4 に答える 4

21

さまざまなオプション(core.autocrlfcore.eol)を試してみたところ、

git am --keep-cr

トリックを実行します(ただし、末尾の空白に関する警告が発生します)。

パッチファイルやその他の汚れを手動で編集する必要はありません。

しかし、(もちろん)ハッシュはnikaiの回答で説明されているように異なります...ハッシュのものを教えてくれたnikaiに感謝します。

私のnotebook-desktop-scenarioで、いくつかの変更をノートブックからデスクトップコンピューターにオフラインで転送したかったのですが、デスクトップにパッチを適用してgit pull desktopからノートブックからを実行したときに、リポジトリが分岐したり、同じコミットが2回発生したりすることはありません。 。

これを達成するために、私は次のことを行いました。

  1. デスクトップで、上記のようにパッチを適用します。git am --keep-cr ...
  2. ノートブックでは、にgit pull desktop、パッチによって導入された各コミットが2回発生する状況になります(元のノートブックコミットに対して1回、パッチが適用されてデスクトップコミットにプルされた場合に1回)
  3. 現在(masterノートブックのブランチにあります)、メッセージへのgit rebase desktop/masterリードを発行No changes -- Patch already appliedし、デスクトップコミットに置き換えられた元のノートブックコミットを開始します
于 2011-07-13T09:47:41.740 に答える
7

Git 2.3.0(2015年2月)は、別の新しいオプションを提案します。--transfer-encoding使用する転送エンコーディング(quoted-printable、8bit、base64)を指定するために、にのみ依存するのではありません --keep-cr

git send-emailマニュアルページ
git amマニュアルページ

PaoloBonziniによるcommit8d81408を参照してくださいbonzini

git-send-email--transfer-encodingオプションを追加

メーリングリストスレッドgit amでは、CRLF行末のリポジトリに「」が付いたパッチを適用する際の問題について詳しく説明しています。
スレッドの例では、リポジトリは ""から作成されているため、その上で友人git-svnを使用することはできません。core.eol

今のところ、最良のオプションは「git am --keep-cr」を使用することです。
ただし、パッチが新しいファイルを作成する場合、パッチ適用プロセスは、「/dev/null\r」ではなく「」文字列を検出するため、新しいファイルを拒否します/dev/null

問題は、SMTPトランスポートがCRLFで安全でないことです。
パッチをメールで送信することは、「」を通過させることと同じdos2unix | unix2dosです。新しく導入されたCRLFは、ストリップする
ため、通常は透明です。git-am設定はkeepcr=trueそれらを保持しますが、ほとんどの場合偶然に機能しており、git amLFとCRLFの行末が混在するリポジトリに""ワークフローがあると非常に問題が発生します。

これに対するMIMEソリューションは、quoted-printabletransferencondingです
これは、受信した電子メールを見るのが恐ろしいものになるため、デフォルトで有効にしたいものではありません。
ただし、CRLF行末をリポジトリに格納するプロジェクトには非常に適しています。

quoted-printableの唯一の欠点は、メンテナが ""を使用すると、quoted-printableパッチが適用されないことですgit am --keep-cr
これは、デコードされたパッチの行末に2つのキャリッジリターンがあるためです。
したがって、base64転送エンコーディングのサポートも追加します。これにより、受信した電子メールをMUA(メールユーザーエージェント)の外部で見ることはまったく不可能になりますが、実際には機能します。

このパッチは、非ASCII文字を含む電子メールの送信を拒否する7ビットのコンテンツ転送エンコーディングも提供することにより、80年代後半にまだ住んでいるユーザーを含むすべてのベースをカバーしています。
そして最後に、「8bit」はContent-Transfer-Encodingヘッダーを追加しますが、それ以外は何もしません。

gitsend-emailのドキュメントには次のものが含まれます。

--transfer-encoding=(7bit|8bit|quoted-printable|base64)

SMTP経由でメッセージを送信するために使用する転送エンコーディングを指定します。
非ASCIIメッセージに遭遇すると、7ビットは失敗します。

Quoted-printableは、リポジトリにキャリッジリターンを含むファイルが含まれている場合に役立ちますが、生のパッチ電子メールファイル(MUAから保存されたもの)を手動で検査するのがはるかに困難になります。

デフォルトは、' sendemail.transferEncoding'構成値の値です。それが指定されていない場合、 git8ビットを使用し、Content-Transfer-Encodingヘッダーを追加しません。


Git 2.32(Q2 2021)で、 " git mailinfo" man(したがって " git am" man--quoted-cr )は、base64またはqpでラップされたCRLFで終わる行の処理方法を制御する""オプションを学習しました。

ĐoànTrầnCôngDanh ()によるcommit 59b519acommit 133a4fdcommit f1aa299commit 0b68956(10 May 2021)、commit dd9323bcommit d582992(06 May 2021)を参照してくださいsgn( Junio C Hamano
によってマージされました---コミット483932a 、20215月16日)gitster

mailinfo:デコードされたbase64/QP電子メールでCRLFが見つかった場合に警告

サインオフ:ĐoànTrầnCôngDanh

SMTPサーバーが8ビットの電子メールメッセージを受信すると、おそらく行末がLFのみである場合、一部のサーバーは、そのLFをCRLFに変更することを決定します。

一部のメーリングリストソフトウェアは、8ビットの電子メールメッセージを受信すると、それらのメッセージをbase64またはquoted-printableでエンコードすることを決定します。

電子メールが上記のメールサーバーを介して転送され、そのようなメーリングリストソフトウェアによって配布される場合、受信者は、別のエンコーディング内にエンコードされたCRLFが含まれるパッチを含む電子メールを受信します。

したがって、そのようなCR(CRLF内)は""で削除できませんでしたmailsplit
そのため、郵送されたパッチをきれいに適用することができませんでした。
そのような事故は野生で観察されています。

これらのメッセージを黙って拒否するのではなく、そのようなCR(CRLFの一部として)が見つかった場合にユーザーに警告を表示しましょう。

警告は次のようになります。

warning: quoted CRLF detected
于 2015-01-31T22:29:11.030 に答える
3

ここにも同様の質問がありました。明らかに同じコミットで異なるsha1が得られるのはなぜですか?

簡単にまとめると、git cat-file commit <sha>ツリー、親、電子メール、日付、作成者またはコミッターの名前が異なるかどうか、またはコミットメッセージに余分な「\n」が導入されているかどうかを絞り込むことができるはずです。

于 2011-07-03T22:28:48.657 に答える
2

短い答え:git am --committer-date-is-author-date

長い話:2つのリポジトリ間でコミットをスニーカーネットで実行しようとしているときに、同じボートに乗っていることに気づきました。のオプションを試した後git am、ファイルIDが常に一致していることに気付きましたが、を連続して実行git amすると、同じオプションに対して異なるコミットIDが生成されていました。通常表示される「作成者」タイムスタンプと、コミットが作成されたときの「コミッター」タイムスタンプの2つのタイムスタンプがあることがわかります。後者は、デフォルトで現在の時刻に設定されていますgit am。日付の同期を維持するオプションが必要です--committer-date-is-author-date。これにより、コミットIDが同期されます。

このため、それgit bundleがあなたの環境のオプションであるならば、それははるかに信頼できると思います。

于 2012-06-28T15:37:40.953 に答える