ProgramingTip

Git에서 파일을 언 스테이징하는 두 가지 방법이있는 이유는 무엇입니까?

bestdevel 2020. 9. 27. 13:19
반응형

Git에서 파일을 언 스테이징하는 두 가지 방법이있는 이유는 무엇입니까?


git은 git rm --cached파일을 언 스테이징 제안 합니다 git reset HEAD file. 어느 것을 선호합니까?

편집하다 :

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

git rm --cached <filePath> 을 파일 언 스테이징하지 않고 실제로 리포지토리 에서 파일을 제거하는-step ( 이전에 이미 커밋되었다고 가정)하지만 작업 트리에 파일을 남겨 둡니다 (추적되지 않은 파일이 남게됩니다).

git reset -- <filePath>unstage 어떤 주어진 파일 (들)에 대한 변화를 개최.

즉, git rm --cached스테이징 된 새 파일에서 경우 기본적으로 이전에 커밋 된 적이 없기 때문에 스테이징을 해제합니다.


git rm --cached색인에서 파일을 제거하는 데 사용됩니다. 파일이 이미 저장소에있는 git rm --cached경우 색인에서 파일을 제거하고 작업 디렉토리에 남겨두고 커밋은 이제 저장소에서도 파일을 제거합니다. 기본적으로 커밋 후 파일의 버전을 해제하고 로컬 복사본을 보관했습니다.

git reset HEAD file(기본적으로 --mixed플래그를 사용하는 ) 파일이 이미 repo에있는 경우 파일의 인덱스 버전을 repo (HEAD)의 인덱스 버전으로 대체하여 수정 사항효과적으로 언 스테이징한다는 점이 다릅니다 .

버전이없는 파일의 경우 파일이 HEAD에 없기 때문에 전체 파일의 스테이징을 해제합니다. 이러한 측면에서 git reset HEAD filegit rm --cached동일하지만합니다 (REPO 이미 파일의 경우에 설명 된대로) 그들은 동일하지 않습니다

의 질문 Why are there 2 ways to unstage a file in git?에-git에서 아무것도 할 수있는 유일한 방법은 없습니다. 그것이 그것의 아름다움입니다 :)


간단히 말해서 :

  • git rm --cached <file> git이 파일 추적을 완전히 중지합니다 (일반 git rm* 와 달리 파일 시스템에 남겨 둡니다 ).
  • git reset HEAD <file> 마지막 커밋 이후 파일에 대한 수정 사항을 언 스테이징합니다 (하지만 명령 이름이 제안하는 것과 달리 파일 시스템에서 되 돌리지 않음 **). 파일은 개정 관리하에 있습니다.

파일이 이전에 개정 제어에 없었던 경우 (예 : git add처음으로 방금 편집 한 파일의 스테이징을 해제하는 경우) 두 명령의 효과가 동일하므로 "두 가지 방법으로 작업 수행 ".

* 이전 에 저장소 에 커밋git rm --cached 된 파일 과 관련하여 @DrewT가 답변에서 언급 한주의 사항을 기억하십시오 . 이 질문의 맥락에서 방금 추가되고 아직 커밋되지 않은 파일에 대해 걱정할 필요가 없습니다.

** 나는 그 이름 때문에 git reset 명령을 사용하는 데 당황 스러울 정도로 오랜 시간이 걸렸다는 사실이 무서웠습니다. 그리고 지금도 여전히 내가 실수하지 않도록 구문을 찾는 경우가 많습니다. ( 업데이트 : 드디어 tldr 페이지에서 의 사용법git reset요약하는 데 시간이 걸렸 으므로 이제 작동 방식에 대한 더 나은 멘탈 모델과 세부 사항을 잊었을 때 빠른 참조 가 생겼 습니다.)


이 스레드는 약간 오래되었지만 여전히 직관적 인 문제가 아니기 때문에 약간의 데모를 추가하고 싶습니다.

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

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

git reset HEAD(없이 -q) 수정 된 파일에 대한 경고를 제공하며 종료 코드는 스크립트에서 오류로 간주되는 1입니다.

편집 : git checkout HEAD to-be-modified to-be-removed스테이징 해제에도 작동하지만 작업 공간에서 변경 사항을 완전히 제거합니다.

업데이트 git 2.23.0 : 때때로 명령이 변경됩니다. 이제 git status말한다 :

  (use "git restore --staged <file>..." to unstage)

... 세 가지 유형의 변경 모두에 적용됩니다.


커밋하고 싶지 않은 파일을 실수로 스테이징하고 변경 사항을 유지하려면 다음을 사용할 수도 있습니다.

git stash
git stash pop

이렇게하면 HEAD에 대한 재설정이 수행되고 변경 사항이 다시 적용되어 커밋을 위해 개별 파일을 다시 준비 할 수 있습니다. 이는 풀 요청 ( git stash ; git checkout -b <feature> ; git stash pop)에 대한 기능 브랜치를 생성하는 것을 잊은 경우에도 유용합니다 .


이 두 명령은 해당 파일이 이미 저장소에 있고 버전 제어 (이전에 커밋 된 등)중인 경우 몇 가지 미묘한 차이가 있습니다.

  • git reset HEAD <file> 현재 커밋에서 파일을 언 스테이징합니다.
  • git rm --cached <file>향후 커밋을 위해 파일을 언 스테이징합니다. 다시 추가 될 때까지 스테이지가 해제됩니다 git add <file>.

그리고 한 가지 더 중요한 차이점이 있습니다.

  • 실행 한 후 git rm --cached <file>원격에 지사를 밀어 원격에서 분기를 당겨 사람이 파일을 얻을 것이다 한 실제 로컬 작업에 단지 추적 된 (즉, 물리적 폴더에서 삭제되지 않음)된다 파일을 설정에도 불구하고, 자신의 폴더에서 삭제합니다.

이 마지막 차이점은 팀의 각 개발자가 다른 구성 (즉, 다른 기본 URL, IP 또는 포트 설정)을 갖는 구성 파일을 포함하는 프로젝트에 중요하므로 git rm --cached <file>브랜치를 끌어 오는 사람을 사용 하는 경우 수동으로 다시 설정해야합니다. 구성을 만들거나 구성을 사용자에게 보내면 삭제가 원격에서 분기를 가져 오는 사람들에게만 영향을 미치기 때문에 ip 설정 (등)으로 다시 편집 할 수 있습니다.


stage를 통해 전체 디렉토리를 사용 한다고 가정 해 보겠습니다 git add <folder>.하지만 준비된 목록 (예 : 실행할 때 생성되는 목록 git status) 에서 파일을 제외하고 제외 된 파일 내에서 수정 사항을 유지하려고 합니다 (작업 중이며 커밋 할 준비가되지 않았지만 당신은 당신의 일을 잃고 싶지 않습니다 ...). 다음을 간단히 사용할 수 있습니다.

git reset <file>

당신이 실행하면 git status, 당신은 그 어떤 파일 (들) 당신이 볼 수 reset있는 unstaged당신이 파일의 나머지 added아직 staged목록을.


1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

( "git rm --cached ..."를 사용하여 언 스테이징)

  • git은 포인터 시스템입니다.

  • 포인터를 변경할 커밋이 아직 없습니다.

  • '가리키는 버킷에서 파일을 가져 오는'유일한 방법 은 git에게 변경 사항을 감시하도록 지시 한 파일제거하는 것입니다.

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

자식 커밋 -ma

  • 당신은 ' 저장 '

삼.

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

( "git reset HEAD ..."를 사용하여 unstage)

  • 이 시점에서 코드를 커밋했습니다.
  • 이제 커밋에 대한 포인터를 재설정 할 수 있습니다. ' 마지막 저장으로 되돌리기 '

아무도 git reflog ( http://git-scm.com/docs/git-reflog )를 언급하지 않았다는 사실에 놀랐습니다 .

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

reflog는 저장소에 대한 변경 사항을 추적 할뿐만 아니라 사용자 작업 (예 : 풀, 다른 분기로 체크 아웃 등)을 추적하고 해당 작업을 취소 할 수있는 git 기록입니다. 따라서 잘못 준비된 파일의 준비를 해제하는 대신 파일을 준비하지 않은 지점으로 되돌릴 수 있습니다.

이는 유사 git reset HEAD <file>하지만 경우에 따라 더 세분화 될 수 있습니다.

죄송합니다-실제로 귀하의 질문에 대답하는 것은 아니지만 내가 자주 사용하는 파일을 언 스테이징하는 또 다른 방법을 가리 킵니다 (나는 Ryan Stewart의 답변을 좋아하고 waldyrious.);) 도움이되기를 바랍니다.


OS 가 버전 관리를 제거하지 않고 디렉토리에서 파일을 제거하는 것처럼 git rm --cached <file>일반 git rm <file>이 둘 다 수행 하는 디렉토리에서 파일을 제거하지 않고 색인에서 파일 제거하는 것처럼 보입니다 rm <file>.


다음을 사용하십시오.

git reset HEAD <filename>

이렇게하면 파일의 스테이징이 해제되고 변경 사항이 유지되므로 원하는 경우 분기를 변경하고 git add해당 파일을 대신 다른 분기로 변경할 수 있습니다 . 모든 변경 사항이 유지됩니다.

참고 URL : https://stackoverflow.com/questions/6919121/why-are-there-two-ways-to-unstage-a-file-in-git

반응형