programing

git-mv의 목적은 무엇입니까?

padding 2023. 5. 28. 20:25
반응형

git-mv의 목적은 무엇입니까?

Git는 파일 이름 변경/이동/복사 작업을 추적할 필요가 없는 것으로 알고 있습니다. 그렇다면 진짜 목적은 무엇입니까?맨 페이지는 특별히 묘사적이지 않아요

쓸모없는 건가요?일반 사용자가 사용하기 위한 것이 아니라 내부 명령입니까?

git mv oldname newname

의 줄임말은 다음과 같습니다.

mv oldname newname
git add newname
git rm oldname

즉, 이전 경로와 새 경로 모두에 대한 인덱스를 자동으로 업데이트합니다.

공식 GitFaq에서:

명령 Git에 이바명있습니다령이름기꾸▁a▁g▁g가 있습니다.git mv하지만 그것은 단지 편의일 뿐입니다. 효과는 이 같은 파일을 추가하는 할 수 .

Git은 단지 당신이 무엇을 하려고 하는지 추측하려고 노력하는 것입니다.그것은 부서지지 않은 역사를 보존하기 위해 모든 노력을 하고 있습니다.물론 완벽하지는 않습니다.그렇게git mv에서는 의도를 명시적으로 설명하고 일부 오류를 방지할 수 있습니다.

이 예를 생각해 보십시오.빈 레포로 시작해서,

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
mv a c
mv b a
git status

결과:

# On branch master
# 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)
#
#   modified:   a
#   deleted:    b
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   c
no changes added to commit (use "git add" and/or "git commit -a")

자동 감지 실패:( 또는 실행했습니까?

$ git add *
$ git commit -m "change"
$ git log c

commit 0c5425be1121c20cc45df04734398dfbac689c39
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

그리고 나서.

$ git log --follow c

Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

commit 50c2a4604a27be2a1f4b95399d5e0f96c3dbf70a
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:45 2013 -0400

    initial commit

이제 대신 시도하십시오(삭제를 기억하십시오)..git실험 시 폴더):

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
git mv a c
git status

지금까지는 좋습니다.

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    a -> c


git mv b a
git status

이제, 아무도 완벽하지 않습니다.

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a
#   deleted:    b
#   new file:   c
#

정말요? 하지만 물론...

git add *
git commit -m "change"
git log c
git log --follow c

. ...그리고 그 결과는 위와 같습니다.--follow전체 내역을 보여줍니다.


이제 이름을 바꿀 때 주의해야 합니다. 두 옵션 모두 여전히 이상한 효과를 낼 수 있습니다.예:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git commit -m "first move"
git mv b a
git commit -m "second move"

git log --follow a

commit 81b80f5690deec1864ebff294f875980216a059d
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:35:58 2013 -0400

    second move

commit f284fba9dc8455295b1abdaae9cc6ee941b66e7f
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:34:54 2013 -0400

    initial b

다음과 비교:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git mv b a
git commit -m "both moves at the same time"

git log --follow a

결과:

commit 84bf29b01f32ea6b746857e0d8401654c4413ecd
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:37:13 2013 -0400

    both moves at the same time

commit ec0de3c5358758ffda462913f6e6294731400455
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:36:52 2013 -0400

    initial a

Ups... 이제 역사는 첫 번째 b가 아닌번째 a로 돌아가고 있는데, 이것은 잘못된 것입니다.그래서 우리가 한 번에 두 가지 동작을 할 때, Git는 혼란스러워졌고 변화를 제대로 추적하지 못했습니다.그런데, 제 실험에서, 제가 사용하는 대신에 파일을 삭제/생성했을 때와 같은 일이 발생했습니다.git mv조심해서 진행하세요. 경고를 받았으니...

@ @ 말했이듯가,git mv속기입니다.

여기서 진짜 질문은 "다른 버전 제어 시스템(예:서브버전 및 Perforce)는 파일 이름을 특별히 처리합니다.Git는 왜 안 그래요?"

리누스는 http://permalink.gmane.org/gmane.comp.version-control.git/217 에서 특유의 재치로 설명합니다.

제발 이 "트랙 파일" 같은 헛소리 좀 그만하세요.Git는 중요한 것, 즉 "파일 모음"을 정확히 추적합니다.다른 어떤 것도 관련이 없으며, 그것이 관련이 있다고 생각하는 것조차도 당신의 세계관을 제한할 뿐입니다.CVS "주석"의 개념이 어떻게 항상 사람들이 그것을 사용하는 방법을 제한하는지 주목하세요.저는 그것이 전혀 쓸모없는 쓰레기라고 생각합니다. 그리고 저는 제가 생각하는 것이 수백만 배 더 유용하다고 생각하는 것을 묘사했습니다. 그리고 그것은 정확히 제가 생각하는 것을 세상의 잘못된 모델로 제한하지 않기 때문입니다.

네치 케이스가 있어요git mv대소문자를 구분하지 않는 파일 시스템에서 파일 이름의 케이스를 변경하려는 경우에도 매우 유용합니다.APFS(mac)와 NTFS(윈도우즈)는 기본적으로 대소문자를 구분하지 않습니다(대소문자는 구분하지 않지만 대소문자는 구분합니다).

그렉.킨델은 CB 베일리의 답변에 대한 댓글에서 이것을 언급합니다.

파일이 합니다.Mytest.txt깃으로 관리하는파일 이름을 다음으로 변경하려는 경우MyTest.txt.

시도해 볼 수 있습니다.

$ mv Mytest.txt MyTest.txt
overwrite MyTest.txt? (y/n [n]) y
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

맙소사.Git는 파일에 어떤 변화가 있었다는 것을 인정하지 않습니다.

문제를 해결하려면 파일 이름을 완전히 바꾼 다음 다시 이름을 변경합니다.

$ mv Mytest.txt temp.txt
$ git rm Mytest.txt
rm 'Mytest.txt'
$ mv temp.txt MyTest.txt
$ git add MyTest.txt 
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt

만세!

아니면 그 모든 번거로움을 덜어줄 수도 있습니다.git mv:

$ git mv Mytest.txt MyTest.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt

git mv파일을 이동하고 인덱스를 업데이트하여 교체된 파일 경로를 기록할 뿐만 아니라 영향을 받는 Git 하위 모듈도 업데이트합니다.수동 이동과 달리 Git에 의해 변경 사항으로 탐지되지 않는 대소문자 전용 이름도 검색합니다.

동일하지는 에서 이전 합니다.git rm다음을 사용하여 새 항목을 인덱스에 추가합니다.git add.

답변 동기 부여

이 질문에는 훌륭한 부분적인 답변이 많이 있습니다.이 대답은 그것들을 하나의 응집력 있는 대답으로 결합하려는 시도입니다.추가적으로, 다른 어떤 대답에서도 언급되지 않은 한 가지는 실제로 맨 페이지가 대부분의 질문에 대답한다는 사실입니다. 하지만 아마도 그것은 그것보다 덜 명확할 것입니다.

자세한 설명

다음 세 가지 효과가 man 페이지에서 호출됩니다.

  1. 파일, 디렉터리 또는 심볼 링크가 파일 시스템에서 이동됩니다.

    git-mv - 파일, 디렉터리 또는 심볼 링크를 이동하거나 이름을 바꿉니다.

  2. 인덱스가 업데이트되고 새 경로가 추가되고 이전 경로가 제거됩니다.

    완료 후 인덱스가 업데이트되지만 변경 내용은 커밋되어야 합니다.

  3. 이동된 하위 모듈이 새 위치에서 작동하도록 업데이트됩니다.

    Git 파일(Git 버전 1.7.8 이상으로 복제되었음을 의미)을 사용하여 하위 모듈을 이동하면 Git 파일 및 코어가 업데이트됩니다.새 위치에서 하위 모듈이 작동하도록 하기 위한 작업 트리 설정.또한 서브모듈 업데이트를 시도합니다.gitmodules(5) 파일의 <name>.path 설정을 지정하고 해당 파일을 준비합니다(-n을 사용하지 않는 경우).

답변에서 언급한 바와 같이,git mv파일 이동, 인덱스에 새 경로 추가 및 인덱스에서 이전 경로 제거와 매우 유사합니다.

mv oldname newname
git add newname
git rm oldname

하지만, 이 대답이 지적하듯이,git mv행동이 이것과 완전히 동일하지는 않습니다.다음을 통해 파일 이동git mv새 경로를 인덱스에 추가하지만 파일의 수정된 내용은 추가하지 않습니다.그러나 세 개의 개별 명령을 사용하면 수정된 내용을 포함하여 전체 파일이 색인에 추가됩니다.이는 파일의 모든 변경 사항을 추가하는 것이 아니라 인덱스를 패치하는 워크플로우를 사용할 때 관련이 있을 수 있습니다.

추가로, 답변과 이 댓글에 언급된 바와 같이,git mv에는 현재 macOS 및 윈도우즈 파일 시스템에서 흔히 있는 것처럼 대소문자를 구분하지 않지만 대소문자를 구분하지 않는 파일 시스템에서 대소문자만 구분하여 이름을 변경할 수 있는 추가적인 이점이 있습니다.예를 들어, 이러한 시스템에서 Git는 다음을 통해 파일을 이동한 후 파일 이름이 변경된 것을 감지하지 못합니다.mv Mytest.txt MyTest.txt에 사하는동을 사용합니다.git mv Mytest.txt MyTest.txt이름을 업데이트했습니다.

다른 용도가 있습니다.git mv위에서 언급하지 않은

를 한 이후로.git add -p(gitadd의 패치 모드, http://git-scm.com/docs/git-add), 참조. 인덱스에 변경 사항을 추가할 때 변경 사항을 검토하는 데 사용하고 싶습니다.따라서 제 워크플로우는 (1) 코드 작업, (2) 색인 검토 및 추가, (3) 커밋이 됩니다.

안녕하십니까?git mv몸에 맞습니까?에는 파을직이는경우다사음용다합니을동하접일다▁if▁using를 사용합니다.git rm그리고.git add모든 변경 사항이 인덱스에 추가되고 gitdiff를 사용하여 변경 사항을 보는 것이 (커밋하기 전에) 덜 쉽습니다.용사를 합니다.git mv에 새 , "" " " " " " " " " 를 사용할 수 있습니다.git diff그리고.git add -p평상시처럼 일하기 위해.

아마도요.git mv이 답변이 게시된 이후로 변경되었으므로 간략하게 업데이트하겠습니다.제가 봤을 때는git mv는 다음에 대한 짧은 손으로 정확하게 설명되지 않습니다.

 # not accurate: #
 mv oldname newname
 git add newname
 git rm oldname

이전 답변에서 설명하지 않은 두 가지 이유로 gitmv를 자주 사용합니다.

  1. 추적된 파일과 추적되지 않은 파일이 혼합된 대형 디렉토리 구조를 이동합니다.추적된 파일과 추적되지 않은 파일이 모두 이동하고 추적/추적 해제 상태를 유지합니다.

  2. 대용량 파일 및 디렉터리를 이동할 때 항상 다음과 같이 가정했습니다.git mv그러면 리포지토리 DB 기록 크기가 줄어듭니다.이는 파일 이동/이름 변경이 인덱스/참조 델타이기 때문입니다.저는 이 가정을 검증하지 않았지만, 논리적으로 보입니다.

언급URL : https://stackoverflow.com/questions/1094269/whats-the-purpose-of-git-mv

반응형