ファイルを手動で移動した後、変更しました。Gitによると、これは新しいファイルであり、削除されたファイルです。Gitに強制的にファイル移動として処理させる方法はありますか?
git mv
がある場合、それらはキャッシュに追加されませんが、追加されgit add
ます。私は、私が使用できるように、ファイルの背を移動することを好むgit mv
、その後、git add -p
私の変更セットを検討します。
ファイルを手動で移動した後、変更しました。Gitによると、これは新しいファイルであり、削除されたファイルです。Gitに強制的にファイル移動として処理させる方法はありますか?
git mv
がある場合、それらはキャッシュに追加されませんが、追加されgit add
ます。私は、私が使用できるように、ファイルの背を移動することを好むgit mv
、その後、git add -p
私の変更セットを検討します。
回答:
変更がそれほど厳しくない場合、Gitは移動/名前変更を自動的に検出します。ただ、git add
新しいファイル、およびgit rm
古いファイル。git status
次に、名前の変更を検出したかどうかを示します。
さらに、ディレクトリ内を移動するには、次の操作が必要になる場合があります。
git add -A .
git status
「新しいファイル」が「名前を変更した」ファイルであることを確認するために実行しますgitステータスに「新しいファイル」が表示され、「名前が変更されていない」場合は、Hank Gayのアドバイスに従って、2つの別々のコミットで移動と変更を行う必要があります。
git status
、git log
またはgit diff
、ないあなたが一度にgit add
、git mv
またはgit rm
。名前の変更の検出についてさらに言えば、ステージングされたファイルに対してのみ意味があります。したがって、git mv
ファイルに変更が続くgit status
と、それはと見なされているように見えますが、ファイルで(と同じ)rename
を使用すると、変更が大きすぎて名前の変更として検出できないことが明らかになります。git stage
git add
git add
。これは、@ jrhorn424が示唆しているように、おそらく一度にリポジトリ全体である必要があります。
移動と変更を別々のコミットで実行します。
git diff
1つのコミットで名前の変更を認識しない場合、2つのコミットで名前の変更を認識しないことです。それには-M
別名--find-renames
を使用する必要があります。したがって、この質問にあなたを導いた動機が(経験から言えば)プルリクエストで名前の変更を確認することである場合、それを2つのコミットに分割しても、その目標に向かって進むことはできません。
それはすべて知覚的なものです。GITはコンテンツトラッカーであるため、Gitは一般に動きの認識に優れています
実際に依存するのは、「stat」がそれを表示する方法です。ここでの唯一の違いは-Mフラグです。
git log --stat -M
commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date: Fri Jan 9 22:13:51 2009 +1300
Category Restructure
lib/Gentoo/Repository.pm | 10 +++++-----
lib/Gentoo/{ => Repository}/Base.pm | 2 +-
lib/Gentoo/{ => Repository}/Category.pm | 12 ++++++------
lib/Gentoo/{ => Repository}/Package.pm | 10 +++++-----
lib/Gentoo/{ => Repository}/Types.pm | 10 +++++-----
5 files changed, 22 insertions(+), 22 deletions(-)
git log --stat
commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date: Fri Jan 9 22:13:51 2009 +1300
Category Restructure
lib/Gentoo/Base.pm | 36 ------------------------
lib/Gentoo/Category.pm | 51 ----------------------------------
lib/Gentoo/Package.pm | 41 ---------------------------
lib/Gentoo/Repository.pm | 10 +++---
lib/Gentoo/Repository/Base.pm | 36 ++++++++++++++++++++++++
lib/Gentoo/Repository/Category.pm | 51 ++++++++++++++++++++++++++++++++++
lib/Gentoo/Repository/Package.pm | 41 +++++++++++++++++++++++++++
lib/Gentoo/Repository/Types.pm | 55 +++++++++++++++++++++++++++++++++++++
lib/Gentoo/Types.pm | 55 -------------------------------------
9 files changed, 188 insertions(+), 188 deletions(-)
git help log
-M
Detect renames.
-C
Detect copies as well as renames. See also --find-copies-harder.
git log -M1 -C1 -B1 -D --find-copies-harder
、を渡すと、gitは新しいファイルが最初にコピーされた可能性があることを「検出」できます。時々これを正しく行うこともあれば、まったく同じ内容の偶然に無関係なファイルを見つけることもあります。
git diff -M
または、実際にそうである限り、マイナーな変更を伴う名前変更git log -M
などの変更を自動的に検出する必要があります。あなたの場合は軽微な変更は軽微なものではなく、あなたが類似threasholdを減らすことができ、例えば
$ git log -M20 -p --stat
デフォルトの50%から20%に減らします。
以下は、コミットされていない1つまたはいくつかの名前が変更および変更されたファイルの迅速でダーティなソリューションです。
ファイルに名前が付けられていてfoo
、名前が付けられているとしますbar
。
bar
一時的な名前に名前を変更します。
mv bar side
チェックアウトfoo
:
git checkout HEAD foo
Gitで名前foo
を変更bar
:
git mv foo bar
一時ファイルの名前をに戻しますbar
。
mv side bar
この最後のステップは、変更されたコンテンツをファイルに戻すものです。
これは機能しますが、移動したファイルのコンテンツが元のgitと大きく異なる場合は、これが新しいオブジェクトであると判断する方が効率的であると見なされます。実演させてください:
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ git add README.md work.js # why are the changes unstaged, let's add them.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ git stash # what? let's go back a bit
Saved working directory and index state WIP on dir: f7a8685 update
HEAD is now at f7a8685 update
$ git status
On branch workit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
nothing added to commit but untracked files present (use "git add" to track)
$ git stash pop
Removing README
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: README
modified: work.js
Dropped refs/stash@{0} (1ebca3b02e454a400b9fb834ed473c912a00cd2f)
$ git add work.js
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: README
$ git add README # hang on, I want it removed
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ mv README.md Rmd # Still? Try the answer I found.
$ git checkout README
error: pathspec 'README' did not match any file(s) known to git.
$ git checkout HEAD README # Ok the answer needed fixing.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: README.md
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ git mv README README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ mv Rmd README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ # actually that's half of what I wanted; \
# and the js being modified twice? Git prefers it in this case.
git mv
単にgit rm
/ git add
ペアの利便性を高めます。すでに「MVバーfoo」でやった場合は、すべてあなたがしなければならないが、あなたがしたことを確認するgit add foo
とgit rm bar
コミット行う前に。これは、単一のgit add -A
コマンドまたは場合によってはgit add foo; git commit -a
シーケンスと同じように実行できます。
add
ファイルを作成すると、gitは移動/変更を削除/追加に分割します。
git commit
、ステップ3の後であれば機能しますが、そうでない場合は正しくありません。また、@ CharlesBaileyは正解です。mv blah foo
ステップ3で通常どおりに簡単に通常の操作を行ってからコミットを実行すると、同じ結果が得られます。
TortoiseGitを使用している場合、Gitの自動名前変更検出はコミット中に発生することに注意することが重要ですが、これが発生するという事実は常にソフトウェアによって常に表示されるとは限りません。2つのファイルを別のディレクトリに移動し、少し編集を行いました。私は自分のコミットツールとしてTortoiseGitを使用しており、[行った変更]リストには、移動ではなく削除および追加されるファイルが表示されていました。コマンドラインからgit statusを実行すると、同様の状況が示されました。ただし、ファイルをコミットした後、ログで名前が変更されたことがわかりました。だからあなたの質問への答えは、あなたがあまりにも極端なことを何もしていない限り、Gitは自動的に名前変更をピックアップするべきです。
編集:どうやら新しいファイルを追加してからコマンドラインからgit statusを実行すると、コミットする前に名前の変更が表示されるはずです。
編集2:さらに、TortoiseGitで、コミットダイアログに新しいファイルを追加しますが、コミットはしません。次に、[ログの表示]コマンドに移動して作業ディレクトリを確認すると、コミットする前にGitが名前の変更を検出したかどうかを確認できます。
同じ質問がここで提起されました:https : //tortoisegit.org/issue/1389そしてここで修正するためにバグとして記録されています:https : //tortoisegit.org/issue/1440 それはTortoiseGitのコミットに関する表示の問題であることがわかりましたダイアログがあり、新しいファイルを追加していない場合はgitステータスにも存在します。
git mv
OSの移動コマンドではなく、コマンドを使用してファイルを移動します。https:
//git-scm.com/docs/git-mv
このgit mv
コマンドはGitバージョン1.8.5以降にのみ存在することに注意してください。したがって、このコマンドを使用するにはGitを更新する必要がある場合があります。
最近、一部のファイルを移動(変更はしない)するときにこの問題が発生しました。
問題は、ファイルを移動したときにGitが一部の行末を変更したため、ファイルが同じであることを認識できなかったことです。
git mv
問題を整理して使用しましたが、それは単一のファイル/ディレクトリでのみ機能し、リポジトリのルートに実行する多くのファイルがありました。
これを修正する1つの方法は、bash /バッチマジックを使用することです。
別の方法は次のとおりです
git commit
。これにより、行末が更新されます。git commit --amend
git commit --amend
。今回は行末に変更がないため、Gitは満足していますこれを行うには、おそらくより良い「コマンドライン」の方法があり、これはハックであることは知っていますが、良い解決策を見つけることはできませんでした。
TortoiseGITの使用:GITコミットで、ファイルの変更が小さい場合でも、一部のファイル移動操作が名前の変更ではなく追加/削除の負荷として表示される場合は、次のようにします。
新しいコミットはファイルの名前変更を正しく表示するようになりました...これは適切なファイル履歴を維持するのに役立ちます。
私がこの質問を理解する方法は、「gitに古いファイルの削除と新しいファイルの作成をファイル移動として認識させる方法」です。
はい作業ディレクトリに、あなたは、古いファイルを削除し、古いファイルを挿入したらgit status
言うだろう「deleted: old_file
」と「Untracked files: ... new_file
」
ただし、ステージングインデックス/レベルでは、gitを使用してファイルを追加および削除すると、ファイルの移動として認識されます。これを行うには、オペレーションシステムを使用して削除と作成を行っていると想定して、次のコマンドを実行します。
git add new_file
git rm old_file
ファイルの内容が50%以上類似している場合、git status
コマンドを実行すると次のようになります。
renamed: old_file -> new_file
git status
「deleted: old_file
」と「Untracked files: ... new_file
」と言う:Git 2.18以降ではない:stackoverflow.com/a/50573107/6309
old_file.txt
、その後git mv old_file.txt new_file.txt
に相当しgit rm --cached old_file.txt
、mv old_file.txt new_file.txt
、git add new_file.txt
。