DevOps/GIT

github #2 github reset

aliceintr 2020. 11. 16. 12:31
반응형

다른 버전의 commit 으로 돌아가고 싶을때 쓰는 명령어는 reset 과 revert 가 있다.

이 작업은 꼭 백업을 만들어서 하기를 추천한다. 미연의 사고를 방지하기 위해서 ..

 

 

Third Commit 과 Second commit 을 지우고 First Commit을 최신버전으로 하고 싶다.

 git reset [지정하고 싶은 최신버전 commit ID] --hard

 

결과를 보다시피 Third Commit 과 Second commit  이 지워진 것을 확인할 수 있다.

**NOTE : 절대 한번 공유된 자원들은 reset을 하지 않는다. 이미 원격 저장소에 올라간 파일들을 말한다. 반드시 본인의 로컬에서만 사용하기 바란다.

 

git revert [돌아가고 싶은 commit ID]

 

 

보다 시피 에러가 발생했다. 그 이유는 Second Commit 에서 부터 S04_Condition.java 라는 파일이 추가 되었는데 이미 최신 commit을 이 파일이 존재하기 이전으로 돌려놓은 상태라서 내 로컬에는 이 파일이 존재하기 않기 때문이다.

이럴 경우 해당 파일을 git add 로 더해준 후 git commit 을 하면 자동으로 revert 가 인식됨

Commit ID 가 변경되면서 최신 버전의 Commit 이 Revert "Third Commit" 으로 변경된것으로 볼수있다.

 

이것을 gistory 버전으로 더 자세히 보도록 하자.

#현재 나의 commit 기록들 여기서 commit 99243bc0c1771b15f51c3fa4df61ebbf94baabcf 버전으로 돌아가고자 한다. 
% git log
commit 324eae6733d5c3e2f1136390cb5a16c003195ce9 (HEAD -> exp, master)
Merge: 97241d3 99243bc
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:35:04 2020 -0500

    master:2

commit 99243bc0c1771b15f51c3fa4df61ebbf94baabcf
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:21:45 2020 -0500

    exp:2

commit 97241d313a561d154603f6621d8e545819d0d133
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:20:51 2020 -0500

    master:1

commit 841c3f71734c66ac1f9b243ebfcac03d182300ba
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:16:00 2020 -0500

#git reset --hard [commit ID]
%git reset --hard 99243bc0c1771b15f51c3fa4df61ebbf94baabcf
HEAD is now at 99243bc exp:2

gistory 들 들어가 보면 현재 나의 체크아웃 브랜치는 exp 이다

보게 되면 commit ID 가 99243bc0c1771b15f51c3fa4df61ebbf94baabcf 로 변경된 것을 알 수 있다.

 

그렇다면 다시 최신버전의 commit으로 돌아 가고 싶을 때는 어떻게 해야할 까?

여기서 ./ORIG_HEAD 파일을 보면 원래버전의 가장 최신 commit ID 가 들어가 있다.

 

또는 ./logs/refs/heads/exp 에서 기록을 찾을 수 도 있다.

이를 터미널에서 확인해보자면 내가 실행한 행위들이 나열되고 그 앞에는 행위에 대한 id가 부여되어있다.

 

% git reflog   

99243bc (HEAD -> exp) HEAD@{0}: reset: moving to 99243bc0c1771b15f51c3fa4df61ebbf94baabcf
324eae6 (master) HEAD@{1}: merge master: Fast-forward
99243bc (HEAD -> exp) HEAD@{2}: checkout: moving from master to exp
324eae6 (master) HEAD@{3}: checkout: moving from exp to master
99243bc (HEAD -> exp) HEAD@{4}: checkout: moving from master to exp
324eae6 (master) HEAD@{5}: commit (merge): master:2
97241d3 HEAD@{6}: checkout: moving from exp to master
99243bc (HEAD -> exp) HEAD@{7}: commit: exp:2
841c3f7 HEAD@{8}: checkout: moving from master to exp
97241d3 HEAD@{9}: commit: master:1
841c3f7 HEAD@{10}: checkout: moving from exp to master
841c3f7 HEAD@{11}: checkout: moving from master to exp
841c3f7 HEAD@{12}: merge exp: Fast-forward
c8d9975 HEAD@{13}: checkout: moving from exp to master
841c3f7 HEAD@{14}: commit: exp:1
c8d9975 HEAD@{15}: checkout: moving from master to exp
c8d9975 HEAD@{16}: checkout: moving from javaDonbina to master
c8d9975 HEAD@{17}: merge master: Fast-forward
190e073 HEAD@{18}: checkout: moving from master to javaDonbina
c8d9975 HEAD@{19}: merge javaDonbina: Merge made by the 'recursive' strategy.
befb17b HEAD@{20}: checkout: moving from master to master
befb17b HEAD@{21}: checkout: moving from javaDonbina to master
190e073 HEAD@{22}: commit: javaDonbina - Tutorial4
1e822b3 HEAD@{23}: checkout: moving from master to javaDonbina
befb17b HEAD@{24}: commit: javaDonbina - Tutorial3
5ccbd61 (java/master) HEAD@{25}: checkout: moving from javaDonbina to master
1e822b3 HEAD@{26}: commit: javaDonbina - Tutorial2
5ccbd61 (java/master) HEAD@{27}: checkout: moving from master to javaDonbina
5ccbd61 (java/master) HEAD@{28}: commit: S03,04 Commit
712c850 HEAD@{29}: commit: Fifth Commit
226927c HEAD@{30}: commit: Delete Unused files and dir
d7ef76c HEAD@{31}: commit: Forth Commit
a3e64da HEAD@{32}: commit: Revert "Third Commit"
2e284f9 HEAD@{33}: reset: moving to 2e284f9f6f055d3d83f85f646f5ff320765f5e7e
ec5ad8e HEAD@{34}: commit: Third Commit
0976134 HEAD@{35}: commit: Second commit
2e284f9 HEAD@{36}: commit: First Commit
1609aef HEAD@{37}: reset: moving to HEAD
1609aef HEAD@{38}: reset: moving to HEAD
1609aef HEAD@{39}: commit (initial): version1

또한 특정 commit 을 바로 checkout 할 수도 있다.

% git checkout 97241d313a561d154603f6621d8e545819d0d133
Note: switching to '97241d313a561d154603f6621d8e545819d0d133'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 97241d3 master:1


% git branch
* (HEAD detached at 97241d3)
  exp
  master

gistory 에서 HEAD 파일이 checkout한 ID로 바뀐것을 볼 수 있다.

다시 최신 버전으로 돌아가자

% git reset --hard 324eae6733d5c3e2f1136390cb5a16c003195ce9

이제 log 에 최신 id 가 나타난것을 볼 수 있다.

% git log
commit 324eae6733d5c3e2f1136390cb5a16c003195ce9 (HEAD -> exp, master)
Merge: 97241d3 99243bc
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:35:04 2020 -0500

    master:2

commit 99243bc0c1771b15f51c3fa4df61ebbf94baabcf
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:21:45 2020 -0500

    exp:2

commit 97241d313a561d154603f6621d8e545819d0d133
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:20:51 2020 -0500

    master:1

commit 841c3f71734c66ac1f9b243ebfcac03d182300ba
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 13:16:00 2020 -0500

    exp:1

 


이제부터는 reset 의 옵션을 알아보자

NAME
       git-reset - Reset current HEAD to the specified state

SYNOPSIS
       git reset [-q] [<tree-ish>] [--] <pathspec>...
       git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
       git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]
       git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

DESCRIPTION
       In the first three forms, copy entries from <tree-ish> to the index. In the last form, set the current branch head (HEAD) to <commit>,
       optionally modifying index and working tree to match. The <tree-ish>/<commit> defaults to HEAD in all forms.

       git reset [-q] [<tree-ish>] [--] <pathspec>..., git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
           These forms reset the index entries for all paths that match the <pathspec> to their state at <tree-ish>. (It does not affect the
           working tree or the current branch.)

           This means that git reset <pathspec> is the opposite of git add <pathspec>. This command is equivalent to git restore
           [--source=<tree-ish>] --staged <pathspec>....

           After running git reset <pathspec> to update the index entry, you can use git-restore(1) to check the contents out of the index to
           the working tree. Alternatively, using git-restore(1) and specifying a commit with --source, you can copy the contents of a path
           out of a commit to the index and to the working tree in one go.

       git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]
           Interactively select hunks in the difference between the index and <tree-ish> (defaults to HEAD). The chosen hunks are applied in
           reverse to the index.

           This means that git reset -p is the opposite of git add -p, i.e. you can use it to selectively reset hunks. See the "Interactive
           Mode" section of git-add(1) to learn how to operate the --patch mode.

       git reset [<mode>] [<commit>]
           This form resets the current branch head to <commit> and possibly updates the index (resetting it to the tree of <commit>) and the
           working tree depending on <mode>. If <mode> is omitted, defaults to --mixed. The <mode> must be one of the following:

           --soft
               Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves
               all your changed files "Changes to be committed", as git status would put it.

           --mixed
               Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what
               has not been updated. This is the default action.

               If -N is specified, removed paths are marked as intent-to-add (see git-add(1)).
           --hard
               Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.

           --merge
               Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which
               are different between the index and working tree (i.e. which have changes which have not been added). If a file that is
               different between <commit> and the index has unstaged changes, reset is aborted.

               In other words, --merge does something like a git read-tree -u -m <commit>, but carries forward unmerged index entries.

           --keep
               Resets index entries and updates files in the working tree that are different between <commit> and HEAD. If a file that is
               different between <commit> and HEAD has local changes, reset is aborted.

           --[no-]recurse-submodules
               When the working tree is updated, using --recurse-submodules will also recursively reset the working tree of all active
               submodules according to the commit recorded in the superproject, also setting the submodules' HEAD to be detached at that
               commit.

       See "Reset, restore and revert" in git(1) for the differences between the three commands.

OPTIONS
       -q, --quiet, --no-quiet
           Be quiet, only report errors. The default behavior is set by the reset.quiet config option.  --quiet and --no-quiet will override
           the default behavior.

       --pathspec-from-file=<file>
           Pathspec is passed in <file> instead of commandline args. If <file> is exactly - then standard input is used. Pathspec elements are
           separated by LF or CR/LF. Pathspec elements can be quoted as explained for the configuration variable core.quotePath (see git-
           config(1)). See also --pathspec-file-nul and global --literal-pathspecs.

       --pathspec-file-nul
           Only meaningful with --pathspec-from-file. Pathspec elements are separated with NUL character and all other characters are taken
           literally (including newlines and quotes).

       --
           Do not interpret any more arguments as options.

       <pathspec>...
           Limits the paths affected by the operation.

           For more details, see the pathspec entry in gitglossary(7).

ref : 생활코딩 - https://youtu.be/4pw4RUaCo0Y

이제 파일 하나를 만들어서 commit 을 해보도록 하자

% vim a.txt 
% cat a.txt
  a
% git add a.txt
% git commit -m "commit : 1"
[master d1f7059] commit : 1
 2 files changed, 1 insertion(+), 3 deletions(-)
 create mode 100644 a.txt
 delete mode 100644 aaa.txt
저장소 working directory index repository - history - tree
a.txt 내용
  a
 

모든 a.txt 내용이 "a" 인것을 확인 할 수 있다.

이제 파일 내용을 바꾸어 보자

%cat a.txt
appple

 

저장소 working directory index repository - history - tree
a.txt 내용 apple a  a

 

% vim a.txt
% cat a.txt
appple1234
% git add a.txt
저장소 working directory index repository - history - tree
a.txt 내용 apple1234 apple1234  a

 

% vim a.txt
% cat a.txt
appple
저장소 working directory index repository - history - tree
a.txt 내용 appple apple1234  a

 

git reset --soft d1f7059851cdf42ab6f30c042c279e272d91c048

% git log
commit d1f7059851cdf42ab6f30c042c279e272d91c048 (HEAD -> master)
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 16:08:11 2020 -0500

    commit : 1
% git log -p
commit d1f7059851cdf42ab6f30c042c279e272d91c048 (HEAD -> master)
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 16:08:11 2020 -0500


    commit : 1

diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+a

repository 내용이 "a" 처음 값으로 변경 된 것을 볼 수 있다.

index 값을 gistory 에서 보면

이제 working directory a.txt 보면

% cat a.txt
appple
저장소 working directory index repository - history - tree
a.txt 내용 appple apple1234  a

이제 최신 버전의 commit 으로 돌아가보록 하자

% git reset --soft ORIG_HEAD

soft 로 그 전 버전 commit으로 돌아 갔기 때문에 똑같은 옵션을 준다 ORIG_HEAD 이 되돌리기 전의 최신 commit정보를 가지고 있음.

% git log
commit 9dfcfaa128ee105b304305b89dd511a655c0bc9a (HEAD -> master)
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 16:08:45 2020 -0500

    commit : 2

commit d1f7059851cdf42ab6f30c042c279e272d91c048
Author: aliceson89 <alice.son1109@gmail.com>
Date:   Thu Nov 19 16:08:11 2020 -0500

    commit : 1

안에 들어있는 내용을 보면

저장소 working directory index repository - history - tree
a.txt 내용 appple apple1234  a

 

이제 는 mixed 로 적용해 보자

% git reset --mixed 9dfcfaa128ee105b304305b89dd511a655c0bc9a
Unstaged changes after reset:
M	a.txt
D	b.txt
% git diff
diff --git a/a.txt b/a.txt
index 7898192..24ec7ce 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1 @@
#index area a.txt 내용
-a

#working directoy a.txt 내용
+appple
저장소 working directory index repository - history - tree
a.txt 내용 appple a  a

 

내용을 보면 index 와 repository area가 다 "a" 로 바뀐것을 볼 수 있다.

왜냐면 2번 commit을 했을 때의 a.txt 상태로 돌아가기 때문에

 

 

이제 hard 옵션을 써보자

% git reset --hard 9dfcfaa128ee105b304305b89dd511a655c0bc9a
HEAD is now at 9dfcfaa commit : 2
% git diff
% cat a.txt
a
저장소 working directory index repository - history - tree
a.txt 내용 a a  a

 

hard 옵션을 쓰면 working directory 내용까지 다 commit :2 번째의 a.txt값으로 바뀌었다. 이미 여러번 working directory 의 내용을 수정했지만 commit이 안되었던 부분이라 다 없어짐.

 

 

 

 

 

 

 

내용이 도움이 되셨다면 블로그 구독하기 부탁드리겠습니다.

* 이 글의 모든 저작권은 aliceintr에 있으며 무단 배포 및 사용은 자제해 주시기 바랍니다. *

반응형

'DevOps > GIT' 카테고리의 다른 글

github#6 git merge conflict  (0) 2020.11.20
github#5 git HEAD file  (0) 2020.11.20
github#4 branch  (0) 2020.11.17
github#3 gistory and git rm  (0) 2020.11.16
github #1 github init, log, diff, add, status, commit  (0) 2020.11.15