- 로컬 변경 사항 되돌리기
- 커밋된 로컬 변경 사항 되돌리기
- 원격 변경사항 되돌리기 - 히스토리 변경 없이
- 원격 변경사항 되돌리기 - 히스토리를 변경하면서
- 커밋을 제거하여 되돌리기
- 새로운 대체 커밋으로 커밋 되돌리기
git revert
와git reset
의 차이- 변경 사항 스테이징 취소
- 관련 주제
변경 사항 되돌리기
Git은 변경 사항을 되돌리는 옵션을 제공합니다. 변경 사항은 Git 워크플로우에서 언제든지 되돌릴 수 있습니다.
변경 사항을 되돌리는 방법은 변경 사항이 다음과 같은지에 따라 다릅니다:
- 로컬 컴퓨터에만 있는 경우.
- GitLab.com과 같은 Git 서버에 원격으로 저장된 경우.
로컬 변경 사항 되돌리기
변경 사항을 원격 저장소에 푸시하기 전까지, Git에서 만든 변경 사항은 로컬 개발 환경에만 있습니다.
스테이지되지 않은 로컬 변경 사항 되돌리기
변경을 했지만 아직 스테이지하지 않은 경우, 작업을 되돌릴 수 있습니다.
-
git add <file>
을 사용하지 않았는지 확인하기 위해git status
를 실행하여 파일이 스테이지되지 않았는지 확인합니다:$ git status On branch main Your branch is up-to-date with 'origin/main'. 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: <file> no changes added to commit (use "git add" and/or "git commit -a")
-
옵션을 선택하고 변경 사항을 되돌립니다:
-
로컬 변경 사항을 덮어쓰려면:
git checkout -- <file>
-
모든 파일에 대한 로컬 변경 사항을 영구적으로 삭제하려면:
git reset --hard
-
스테이지된 로컬 변경 사항 되돌리기
파일을 스테이징에 추가한 경우, 이를 되돌릴 수 있습니다.
-
git add <file>
을 사용했는지 확인하기 위해git status
를 실행하여 파일이 스테이지되었는지 확인합니다:$ git status On branch main Your branch is up-to-date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: <file>
-
옵션을 선택하고 변경 사항을 되돌립니다:
-
파일의 스테이지를 해제하지만 변경 사항을 유지하려면:
git restore --staged <file>
-
모든 것의 스테이지를 해제하지만 변경 사항을 유지하려면:
git reset
-
현재 커밋(HEAD)으로 파일의 스테이지를 해제하려면:
git reset HEAD <file>
-
모든 것을 영구적으로 삭제하려면:
git reset --hard
-
커밋된 로컬 변경 사항 되돌리기
로컬 저장소에 커밋(git commit
)하면, Git이 변경 사항을 기록합니다. 아직 원격 저장소에 푸시하지 않았으므로, 변경 사항은 공개되지 않았습니다(또는 다른 개발자와 공유되지 않습니다). 이 시점에서, 변경 사항을 되돌릴 수 있습니다.
기록을 수정하지 않고 스테이지된 로컬 변경 사항 되돌리기
커밋 히스토리를 유지하면서 커밋을 되돌릴 수 있습니다.
이 예제는 커밋 A
,B
,C
,D
,E
가 순서대로 커밋된 다섯 개의 커밋을 사용합니다: A-B-C-D-E
.
되돌리려는 커밋은 B
입니다.
-
되돌리려는 커밋의 SHA를 찾습니다. 커밋 로그를 보려면
git log
를 입력합니다. -
옵션을 선택하고 변경 사항을 되돌립니다:
-
커밋
B
에 의해 도입된 추가 및 삭제 변경 사항을 교환하려면:git revert <commit-B-SHA>
-
커밋
B
에서 하나의 파일 또는 디렉터리의 변경 사항을 되돌리되, 스테이지 상태로 유지하려면:git checkout <commit-B-SHA> <file>
-
커밋
B
에서 하나의 파일 또는 디렉터리의 변경 사항을 되돌리되, 스테이지되지 않은 상태로 유지하려면:git reset <commit-B-SHA> <file>
-
여러 개의 커밋된 변경 사항 되돌리기
여러 커밋에서 복구할 수 있습니다. 예를 들어, 브랜치에서 A-B-C-D
커밋을 했고, C
와 D
가 잘못되었다고 생각해 보세요.
잘못된 여러 커밋에서 복구하려면:
-
마지막으로 올바른 커밋을 체크아웃합니다. 이 예에서는
B
입니다.git checkout <commit-B-SHA>
-
새 브랜치를 생성합니다.
git checkout -b new-path-of-feature
-
변경 사항을 추가하고, 푸시하고, 커밋합니다.
커밋은 이제 A-B-C-D-E
입니다.
또는, GitLab을 사용하여,
체리 픽하여 새 병합 요청으로 그 커밋을 가져올 수 있습니다.
B
로 리셋하고 E
를 커밋하는 것입니다. 그러나 이 솔루션은 A-B-E
로 결과가 나와 다른 개발자들이 로컬에서 가지고 있는 것과 충돌합니다.히스토리 수정을 통한 스테이지된 로컬 변경 사항 되돌리기
다음 섹션에서는 Git 히스토리를 다시 쓰는 작업을 문서화합니다. 자세한 내용은
리베이스 중에 발생하는 일을 참조하세요.
특정 커밋 삭제하기
특정 커밋을 삭제할 수 있습니다. 예를 들어, A-B-C-D
커밋이 있으며 B
커밚을 삭제하고 싶다면.
-
현재 커밋
D
에서B
까지의 범위를 리베이스합니다:git rebase -i A
커밋 목록이 에디터에 표시됩니다.
- 커밋
B
앞에서pick
을drop
으로 교체합니다. - 다른 모든 커밋에는 기본값인
pick
을 남겨둡니다. - 에디터를 저장하고 종료합니다.
특정 커밋 수정하기
특정 커밋을 수정할 수 있습니다. 예를 들어, A-B-C-D
커밋이 있으며 커밋 B
에서 도입된 무언가를 수정하고 싶다면.
-
현재 커밋
D
에서B
까지의 범위를 리베이스합니다:git rebase -i A
커밋 목록이 에디터에 표시됩니다.
- 커밋
B
앞에서pick
을edit
로 교체합니다. - 다른 모든 커밋에는 기본값인
pick
을 남겨둡니다. - 에디터를 저장하고 종료합니다.
-
에디터에서 파일을 열고 수정을 하고 변경 사항을 커밋합니다:
git commit -a
되돌린 작업 다시 실행하기
이전의 로컬 커밋을 호출할 수 있습니다. 그러나 모든 이전 커밋이 사용 가능한 것은 아니며,
Git은 정기적으로 브랜치나 태그에 의해 도달할 수 없는 커밋을 정리합니다.
저장소 히스토리를 보고 이전 커밋을 추적하려면 git reflog show
를 실행합니다. 예를 들면:
$ git reflog show
# 예제 출력:
b673187 HEAD@{4}: merge 6e43d5987921bde189640cc1e37661f7f75c9c0b: '재귀적' 전략으로 병합함.
eb37e74 HEAD@{5}: rebase -i (finish): refs/heads/master로 돌아감
eb37e74 HEAD@{6}: rebase -i (pick): 커밋 C
97436c6 HEAD@{7}: rebase -i (start): checkout 97436c6eec6396c63856c19b6a96372705b08b1b
...
88f1867 HEAD@{12}: commit: 커밋 D
97436c6 HEAD@{13}: checkout: 97436c6eec6396c63856c19b6a96372705b08b1b에서 test로 이동
97436c6 HEAD@{14}: checkout: master에서 97436c6으로 이동
05cc326 HEAD@{15}: commit: 커밋 C
6e43d59 HEAD@{16}: commit: 커밋 B
이 출력은 저장소 히스토리를 보여주며, 다음을 포함합니다:
- 커밋 SHA.
- 커밋이 만들어진 이후
HEAD
변경 작업의 수 (HEAD@{12}
는 12개의HEAD
변경 작업 전에 만들어졌습니다). - 수행된 작업, 예: 커밋, 리베이스, 병합.
-
HEAD
를 변경한 작업의 설명.
원격 변경사항 되돌리기 - 히스토리 변경 없이
원격 저장소에서 변경사항을 되돌리려면, 되돌리려는 변경사항으로 새 커밋을 생성할 수 있습니다.
이 프로세스를 따르면 히스토리를 보존하고 명확한 타임라인과 개발 구조를 제공합니다.
그러나, 다른 개발자들이 작업의 기반으로 사용하는 브랜치에 작업이 병합된 경우에만 이 절차가 필요합니다.
특정 커밋 B
에서 도입된 변경사항을 되돌리려면:
git revert B
원격 변경사항 되돌리기 - 히스토리를 변경하면서
원격 변경사항을 되돌리고 히스토리를 변경할 수 있습니다.
업데이트된 히스토리에서도 이전 커밋은 커밋 SHA를 통해 여전히 접근할 수 있습니다.
이것은 분리된 커밋의 자동 정리가 수행되거나 수동으로 정리가 실행될 때까지의 경우입니다.
정리 중에도 여전히 참조가 존재한다면 이전 커밋이 제거되지 않을 수 있습니다.
히스토리 변경이 허용되는 경우
공개 브랜치에서 작업하거나 다른 개발자가 사용할 수 있는 브랜치에서 작업할 때는 히스토리를 변경하면 안 됩니다.
GitLab과 같은 대규모 오픈 소스 저장소에 기여할 때는 커밋을 하나로 스쿼시할 수 있습니다.
병합 시 자신의 브랜치에서 타겟 브랜치로 커밋을 하나로 스쿼시하려면 git merge --squash
를 사용하세요.
히스토리 변경 방법
병합 요청의 브랜치는 공개 브랜치이며 다른 개발자들이 사용할 수 있습니다.
하지만 프로젝트 규칙에 따라 리뷰가 완료된 후 타겟 브랜치에서 표시된 커밋 수를 줄이기 위해 git rebase
를 사용해야 할 수도 있습니다.
git rebase -i
를 사용하여 히스토리를 수정할 수 있습니다.
이 명령어를 사용하여 커밋을 수정하고, 스쿼시하고, 삭제하세요.
#
# 명령어:
# p, pick = 커밋 사용
# r, reword = 커밋 사용, 하지만 커밋 메시지 수정
# e, edit = 커밋 사용, 하지만 수정하기 위해 중단
# s, squash = 커밋 사용, 하지만 이전 커밋과 합치기
# f, fixup = "squash"와 같지만, 이 커밋의 로그 메시지를 버립니다.
# x, exec = 쉘을 사용해 명령어(나머지 줄) 실행
# d, drop = 커밋 제거
#
# 이 줄들은 재배열할 수 있으며, 상단에서 하단으로 실행됩니다.
#
# 줄을 제거하면 해당 커밋이 손실됩니다.
#
# 그러나 모든 것을 제거하면 리베이스가 중단됩니다.
#
# 빈 커밋은 주석 처리되어 있습니다.
대신 주석 없는 모든 줄을 제거하고 저장하세요.
공유 및 원격 브랜치에서 git rebase
를 주의 깊게 사용하세요.
원격 저장소로 푸시하기 전에 로컬에서 실험해 보세요.
# 커밋 ID에서 HEAD(현재 커밋)까지 히스토리 수정
git rebase -i commit-id
텍스트 삭제
- GitLab 17.1에서 도입됨 플래그를 사용하여
rewrite_history_ui
라는 이름으로. 기본적으로 비활성화되어 있습니다.- GitLab.com에서 활성화됨 GitLab 17.2에서.
- 자체 관리 및 GitLab 전용에서 활성화됨 GitLab 17.3에서.
우연히 커밋된 민감하거나 기밀 정보는 영구적으로 삭제하여 더 이상 저장소의 히스토리에서 접근할 수 없도록 합니다.
문자열 목록을 ***REMOVED***
로 대체합니다.
특정 파일을 저장소에서 완전히 삭제하려면 Blob 제거를 참조하세요.
전제 조건:
- 프로젝트에 대한 소유자 역할이 있어야 합니다.
저장소에서 텍스트를 삭제하려면:
- 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
- 설정 > 저장소를 선택합니다.
- 저장소 유지 관리를 확장합니다.
- 텍스트 삭제를 선택합니다.
- 서랍에서 삭제할 텍스트를 입력합니다. 정규 표현식 및 글로브 패턴을 사용할 수 있습니다.
- 일치하는 문자열 삭제를 선택합니다.
- 확인 대화 상자에서 프로젝트 경로를 입력합니다.
- 예, 일치하는 문자열 삭제를 선택합니다.
- 왼쪽 사이드바에서 설정 > 일반을 선택합니다.
- 고급을 확장합니다.
- 정리 실행을 선택합니다.
커밋에서 민감한 정보 삭제
Git을 사용하여 이전 커밋에서 민감한 정보를 삭제할 수 있습니다. 그러나 이 과정에서 기록이 수정됩니다.
certain filters를 사용하여 기록을 다시 작성하려면 git filter-branch
를 실행하세요.
전체 기록에서 파일을 제거하려면:
git filter-branch --tree-filter 'rm filename' HEAD
git filter-branch
명령은 대형 리포지토리에서 느릴 수 있습니다.
보다 빠르게 Git 명령을 실행할 수 있는 도구들이 있습니다.
이러한 도구들은 git filter-branch
와 동일한 기능 세트를 제공하지 않지만 특정 사용 사례에 초점을 맞추기 때문에 더 빠릅니다.
리포지토리 기록과 GitLab 저장소에서 파일을 삭제하는 것에 대한 자세한 내용은 리포지토리 크기 줄이기를 참조하세요.
커밋을 제거하여 되돌리기
-
마지막 커밋을 되돌리고 모든 내용을 스테이징 영역으로 되돌립니다:
git reset --soft HEAD^
-
파일을 추가하고 커밋 메시지를 변경합니다:
git commit --amend -m "New Message"
-
마지막 변경을 취소하고 모든 다른 변경 사항을 제거합니다, 푸시하지 않았다면:
git reset --hard HEAD^
-
마지막 변경을 취소하고 마지막 두 커밋을 제거합니다, 푸시하지 않았다면:
git reset --hard HEAD^^
Git 리셋 샘플 워크플로우
다음은 일반적인 Git 리셋 워크플로우입니다:
- 파일을 수정합니다.
-
브랜치의 상태를 확인합니다:
git status
-
잘못된 커밋 메시지로 브랜치에 변경 사항을 커밋합니다:
git commit -am "kjkfjkg"
-
Git 로그를 확인합니다:
git log
-
올바른 커밋 메시지로 커밋을 수정합니다:
git commit --amend -m "New comment added"
-
Git 로그를 다시 확인합니다:
git log
-
브랜치를 소프트 리셋합니다:
git reset --soft HEAD^
-
Git 로그를 다시 확인합니다:
git log
-
원격에서 브랜치의 업데이트를 가져옵니다:
git pull origin <branch>
-
원격에 브랜치의 변경 사항을 푸시합니다:
git push origin <branch>
새로운 대체 커밋으로 커밋 되돌리기
git revert <commit-sha>
git revert
와 git reset
의 차이
-
git reset
명령은 커밋을 제거합니다.git revert
명령은 변경 사항을 제거하지만 커밋은 남겨 둡니다. -
git revert
명령은 더 안전합니다. 왜냐하면 되돌리기를 다시 되돌릴 수 있기 때문입니다.
# 변경된 파일
git commit -am "bug introduced"
git revert HEAD
# 변경 사항을 되돌리는 새로운 커밋 생성
# 이제 되돌린 커밋을 다시 적용하고 싶습니다
git log # 되돌린 커밋에서 해시 가져오기
git revert <rev commit hash>
# 되돌린 커밋이 복구되었습니다(새 커밋이 다시 생성됨)
변경 사항 스테이징 취소
파일을 Git에서 스테이징 하면 Git에 변경 사항을 추적하도록 지시하여 커밋 준비를 합니다. 파일에 대한 변경 사항을 무시하고 다음 커밋에 포함되지 않도록 하려면 파일의 스테이징을 취소 합니다.
파일의 스테이징 취소
-
파일을 스테이징에서 제거하되 변경 사항은 유지하려면:
git reset HEAD <file>
-
마지막 세 커밋의 스테이징을 취소하려면:
git reset HEAD^3
-
HEAD에서 특정 파일에 대한 변경 사항의 스테이징을 취소하려면:
git reset <filename>
파일의 스테이징을 취소한 후, 파일을 변경 전 상태로 되돌리려면:
git checkout -- <file>
파일 제거
-
디스크와 리포지토리에서 파일을 제거하려면
git rm
을 사용하세요. 디렉토리를 제거하려면-r
플래그를 사용하세요:git rm '*.txt' git rm -r <dirname>
-
파일을 디스크에 유지하되 리포지토리에서 제거하려면(예:
.gitignore
에 추가할 파일)--cache
플래그와 함께rm
명령을 사용하세요:git rm <filename> --cache
이 명령은 현재 브랜치에서 파일을 제거하지만, 리포지토리의 기록에서 완전히 삭제하지는 않습니다.
파일의 과거와 현재의 모든 흔적을 리포지토리에서 완전히 제거하려면 Remove blobs를 참조하세요.