[git] 자식에서 파일 이름 바꾸기 처리

git 에서 파일 이름을 바꿀변경 사항을 커밋하고 이름을 변경 한 다음 이름을 바꾼 파일을 준비해야 한다는 것을 읽었습니다 . Git은 파일을 새로운 추적되지 않은 파일로 보는 대신 내용에서 파일을 인식하고 변경 기록을 유지합니다.

그러나 오늘 밤 에이 작업을 수행하면 결국으로 되돌아갔습니다 git mv.

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.html
#

Finder에서 내 스타일 시트의 이름을 iphone.css에서mobile.css

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.html
#
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    css/iphone.css
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   css/mobile.css

git은 이제 하나의 CSS 파일을 삭제하고 새로운 파일을 추가했다고 생각합니다. 내가 원하는 것이 아니라 이름 바꾸기를 취소하고 자식이 작업을 수행하도록하십시오.

> $ git reset HEAD .
Unstaged changes after reset:
M   css/iphone.css
M   index.html

내가 시작한 곳으로 돌아갑니다.

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.html
#

git mv대신 사용할 수 있습니다 .

> $ git mv css/iphone.css css/mobile.css
> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    css/iphone.css -> css/mobile.css
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   index.html
#

우리가 좋아 보인다. 왜 Finder를 사용할 때 처음으로 이름 바꾸기를 인식하지 못했습니까?



답변

대한 매뉴얼 페이지가
말한다git mv

성공적으로 완료되면 색인이 업데이트됩니다. […]

따라서 처음에는을 사용하여 색인을 직접 업데이트해야합니다 git add mobile.css. 그러나
git status
여전히 두 개의 다른 파일이 표시됩니다

$ git status
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       new file:   mobile.css
#
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       deleted:    iphone.css
#

을 실행하여 다른 출력을 얻을 수 있습니다.
git commit --dry-run -a결과는 다음과 같습니다.

Tanascius@H181 /d/temp/blo (master)
$ git commit --dry-run -a
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       renamed:    iphone.css -> mobile.css
#

우리 사이의 이러한 차이를 볼 이유는 정확히 말할 수 없어 git status하고
git commit --dry-run -a, 그러나 여기에서 힌트
라이너스 :

git은 내부적으로 “이름 변경 감지”전체를 신경 쓰지 않으며 , 이름 바꾸기로 수행 한 커밋 은 이름 바꾸기 를 표시 하는 휴리스틱과 완전히 독립적입니다 .

A dry-run는 실제 이름 바꾸기 메커니즘을 사용하지만
git status아마도 그렇지 않습니다.


답변

git이 파일을 이동으로 인식하기 전에 수정 된 두 파일을 인덱스에 추가해야합니다.

mv old newgit mv old newgit mv 의 유일한 차이점 은 파일을 인덱스에 추가한다는 것입니다.

mv old new다음 git add -A, 너무 일 것이다.

git add .인덱스에 제거를 추가하지 않기 때문에 사용할 수 는 없습니다.

“git add -A”와 “git add의 차이점을 참조하십시오 .”


답변

가장 좋은 것은 직접 시도해 보는 것입니다.

mkdir test
cd test
git init
touch aaa.txt
git add .
git commit -a -m "New file"
mv aaa.txt bbb.txt
git add .
git status
git commit --dry-run -a

이제 git status와 git commit –dry-run -a는 git status가 bbb.txt를 새 파일로 표시하고 aaa.txt가 삭제되고 –dry-run 명령이 실제 이름을 바꾸는 두 가지 결과를 보여줍니다.

~/test$ git status

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   bbb.txt
#
# 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:    aaa.txt
#


/test$ git commit --dry-run -a

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

이제 체크인을 진행하십시오.

git commit -a -m "Rename"

이제 파일의 이름이 바뀌었고 git status에 표시된 것이 잘못되었음을 알 수 있습니다.

이야기의 교훈 : 파일 이름이 바뀌 었는지 확실하지 않으면 “git commit –dry-run -a”를 발행하십시오. 파일 이름이 바뀌 었다는 메시지가 표시되면 계속 진행하십시오.


답변

git 1.7.x의 경우 다음 명령이 효과적이었습니다.

git mv css/iphone.css css/mobile.css
git commit -m 'Rename folder.'

원래 파일 (예 : css / mobile.css)이 이미 커밋 된 파일에 있었기 때문에 git add가 필요하지 않았습니다.


답변

당신은에있는 git add css/mobile.css새 파일과 git rm css/iphone.css자식 그것에 대해 알 수 있도록. 그런 다음 동일한 출력을 표시합니다git status

상태 출력 (파일의 새 이름)에서 명확하게 볼 수 있습니다.

# Untracked files:
#   (use "git add <file>..." to include in what will be committed)

그리고 (이전 이름) :

# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)

나는 배후에서 git mv정확히 그것을하는 래퍼 스크립트 일뿐이라고 생각 합니다. 인덱스에서 파일을 삭제하고 다른 이름으로 추가하십시오.


답변

자식 관점에서 파일을 생각해 봅시다.

git은 파일에 대한 메타 데이터를 추적하지 않습니다.

귀하의 저장소는 (다른 것들 중에서)

$ cd repo
$ ls
...
iphone.css
...

그리고 git control하에 있습니다 :

$ git ls-files --error-unmatch iphone.css &>/dev/null && echo file is tracked
file is tracked

이것을 사용하여 테스트하십시오 :

$ touch newfile
$ git ls-files --error-unmatch newfile &>/dev/null && echo file is tracked
(no output, it is not tracked)
$ rm newfile

당신이 할 때

$ mv iphone.css mobile.css

자식 관점에서

  • iphone.css 가 없습니다 (삭제됨 -git 경고).
  • 새로운 파일 mobile.css가 있습니다.
  • 이 파일들은 완전히 관련이 없습니다.

따라서 git은 이미 알고있는 파일 ( iphone.css )과 감지하는 새 파일 ( mobile.css ) 에 대해 조언 하지만 파일이 색인에 있거나 HEAD git가 내용을 확인하기 시작할 때만 해당합니다.

현재 “iphone.css 삭제”또는 mobile.css 가 모두 색인에 없습니다.

색인에 iphone.css 삭제 추가

$ git rm iphone.css

git은 정확히 무슨 일이 있었는지 알려줍니다 : ( iphone.css 는 삭제됩니다. 더 이상 일어난 일은 없습니다)

그런 다음 새 파일 mobile.css 를 추가하십시오.

$ git add mobile.css

이번에는 삭제와 새 파일이 모두 색인에 있습니다. 이제 git은 컨텍스트가 동일하다는 것을 감지하고 이름을 바꿉니다. 실제로 파일이 50 % 유사하면 이름이 바뀌는 것을 감지 하여 작업 이름을 그대로 유지하면서 mobile.css 를 약간 변경할 수 있습니다 .

에서 재현 할 수 있음을 참조하십시오 git diff. 이제 파일이 색인에 있으므로를 사용해야합니다 --cached. mobile.css 를 약간 편집 하고 색인에 추가하고 다음의 차이점을 확인하십시오.

$ git diff --cached

$ git diff --cached -M

-M에 대한 “이름 바꾸기 감지”옵션입니다 git diff. -M-M50%(50 % 이상의 유사성으로 인해 git이이를 이름 바꾸기로 표시 함)을 의미하지만 -M20%mobile.css를 많이 편집하면 이를 (20 %)로 줄일 수 있습니다 .


답변

1 단계 : 파일 이름을 oldfile에서 newfile로 바꿉니다.

git mv #oldfile #newfile

2 단계 : 자식 커밋 및 주석 추가

git commit -m "rename oldfile to newfile"

3 단계 :이 변경 사항을 원격 서버로 푸시

git push origin #localbranch:#remotebranch