Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

이지은님의 블로그

240217 - Git: IntelliJ에서 제공하는 Git 기능(Cherry-pick, Reset current Branch) 본문

TIL

240217 - Git: IntelliJ에서 제공하는 Git 기능(Cherry-pick, Reset current Branch)

queenriwon3 2025. 2. 17. 23:47

▷ 오늘 배운 것

팀 프로젝트를 하면서 협업 툴인 git 과 github의 사용에 대한 중요성이 커지고 있다. 따라서 git 사용 공부를 조금씩 해보려고 한다.

 

다음 이미지에서 인텔리제이에서 제공하는 기능에 대해 알아보자

 

 

<<목차>>

1. Copy Revision Number

2. Create Patch…

3. Cherry-pick

4. Checkout revision

5. Show repository at revision

6. Compare with local

7. Reset current Branch to Here…

 

 


 

 

 

1. Copy Revision Number

: 선택한 커밋의 해시번호를 복사, 특정 커밋을 참조할 때 사용

 

커밋 해시 번호를 가져오고 싶을 때 복사할 수 있는데, 다음과 같은 커밋 해시번호를 얻을 수 있다.

656189e23fa230d5aa31052f3849415e7e3dcefb



 

2. Create Patch…

현재 선택한 커밋이나 변경사항을 .patch 파일로 만들어 다른 개발자에게 공유하거나 다른 프로젝트에 적용할 때 사용된다.

 

옵션 중 클립보드 형태로 복사할 수도 있는데, 확인하면 다음과 같은 내용을 확인 할 수 있다. 

어떤 코드 파일의 어떤 부분을 수정했는지 해시코드와 함께 확인할 있다.

Subject: [PATCH] fix: 댓글 수정 삭제 scheduleId제거
---
Index: src/main/java/com/example/scheduledevelopproject/controller/CommentController.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/com/example/scheduledevelopproject/controller/CommentController.java b/src/main/java/com/example/scheduledevelopproject/controller/CommentController.java
--- a/src/main/java/com/example/scheduledevelopproject/controller/CommentController.java	(revision dc3edff015f869015d8b220b3128496f7a894fb1)
+++ b/src/main/java/com/example/scheduledevelopproject/controller/CommentController.java	(revision 656189e23fa230d5aa31052f3849415e7e3dcefb)
@@ -46,27 +46,25 @@
     }
 
     @LoginRequired
-    @PatchMapping("/{scheduleId}/comments/{commentId}")
+    @PatchMapping("/comments/{commentId}")
     public ApiResponseDto<CommentResponseDto> updateComment(
-            @PathVariable Long scheduleId,
             @PathVariable Long commentId,
             @Valid @RequestBody CommentRequestDto dto,
             @SessionUser SessionUserDto userSession
     ) {
         CommentResponseDto commentResponseDto = commentService.updateComment(commentId, userSession.getId(), dto);
-        log.info("id {} 일정 댓글 수정", scheduleId);
-        return ApiResponseDto.OK(commentResponseDto,"id" + scheduleId + " 일정 댓글 수정");
+        log.info("id {} 댓글 수정", commentId);
+        return ApiResponseDto.OK(commentResponseDto,"id" + commentId + " 댓글 수정");
     }
 
     @LoginRequired
-    @DeleteMapping("/{scheduleId}/comments/{commentId}")
+    @DeleteMapping("/comments/{commentId}")
     public ApiResponseDto<Void> deleteComment(
-            @PathVariable Long scheduleId,
             @PathVariable Long commentId,
             @SessionUser SessionUserDto userSession
     ) {
         commentService.deleteComment(commentId, userSession.getId());
-        log.info("id {} 일정 댓글 삭제", scheduleId);
-        return ApiResponseDto.OK("id" + scheduleId + " 일정 댓글 삭제");
+        log.info("id {} 댓글 삭제", commentId);
+        return ApiResponseDto.OK("id" + commentId + " 댓글 삭제");
     }
 }
Index: src/main/java/com/example/scheduledevelopproject/service/ScheduleService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/com/example/scheduledevelopproject/service/ScheduleService.java b/src/main/java/com/example/scheduledevelopproject/service/ScheduleService.java
--- a/src/main/java/com/example/scheduledevelopproject/service/ScheduleService.java	(revision dc3edff015f869015d8b220b3128496f7a894fb1)
+++ b/src/main/java/com/example/scheduledevelopproject/service/ScheduleService.java	(revision 656189e23fa230d5aa31052f3849415e7e3dcefb)
@@ -31,7 +31,7 @@
 
         Schedules saveSchedule = scheduleRepository.save(schedules);
 
-        return new ScheduleResponseDto(findSchedulesByIdOrElseThrow(saveSchedule.getId()));
+        return new ScheduleResponseDto(saveSchedule);
     }
 
     @Transactional(readOnly = true)

 

 

 

3. Cherry-pick

특정 커밋을 뽑아서 현재 브런치에 적용할 수 있다.

실무에서는 특정 내용만 런칭하기 위해 따로 브런치를 파고 그 특정내용만 cherry-pick하여 브런치에 적용, 그 브런치를 main으로 릴리즈 할때 사용한다.

 

이때 결국은 선택한 것과 merge 하는 것이기 때문에 충돌이 발생할 있다는 점을 주의하자.

 

이런 충돌 창이 노출 되었을 때, 각 버튼의 뜻은 다음과 같다.

(현재 상황은 main 브런치에서 Interceptor라는 브런치의 주석을 단 커밋을 가져온 상황이다.)

 

1️⃣ Accept Yours (내 변경 사항 유지)

: 내 변경 사항을 유지하고, 체리픽된 커밋의 변경 사항을 무시함

즉, 현재 브랜치에서 작업하던 내 코드(main)가 유지되고, cherry-pick을 시도한 커밋(interceptor)의 변경 사항이 적용되지 않음.

 

2️⃣ Accept Theirs (체리픽한 커밋 적용)

: cherry-pick하려는 커밋의 변경사항을 적용하고, 내 변경 사항을 무시함

즉, 현재 브랜치에서 작업하던 내 코드(mai가 사라지고, 체리픽된 커밋의 코드가 그대로 적용됨.

 

3️⃣ Merge… (수동 병합)

: 직접 충돌을 해결할 수 있도록 에디터가 열리며, 충돌된 코드의 각 부분을 비교하면서 직접 해결할 수 있음.

 

 

충돌을 해결하고 나면 다음과 같이 해당 커밋부분만 뽑아서 적용시킬 있다.

 

 

 

4. Checkout revision

특정 커밋으로 체크 아웃 있다. 이때 브런치를 따로 만들어서 작업하는 것이 권장된다.(HEAD 브랜치가 아닌 커밋으로 설정됨 —> Head detached 상태)

 

 

 

Head detached 상태가 된다는 의미가 뭘까?

현재 작업중이 head가 특정 브랜치가 아닌 특정 커밋을 가리키고 있는 상태라는 뜻이다.(브랜치가 아닌 특정 커밋)

혹은 IntelliJ에서 Cherry-Pick 도중 충돌 해결 후 적용하거나, checkout revision을 사용했을 때, 그 커밋을 직접 참조하는 상태가 되어 detached HEAD 상태가 될 수 있다.

 

이 상태에서 커밋을 만들면, 브랜치가 없기 때문에 해당 커밋을 찾을 수 가 없는 경우가 발생한다.

이를 해결하기 위해 Head detached 상태가 되면 새로운 브랜치를 만들어서 저장한다.

 

Git branch Head detached 상태 확인 가능

 

 

 

 

5. Show repository at revision

해당 커밋이 적용된 시점의 프로젝트 상태를 탐색할 수 있다. 특정 커밋의 코드가 어떻게 구성이 되어있는지 확인이 가능하다.

 

하나씩 파일을 열어보면서 확인이 가능하다.

 

 

 

 

6. Compare with local

선택한 커밋과 현재 로컬 코드의 차이를 비교할 수 있다.

변경된 파일을 확인 있으며, 무엇이 수정이되고 삭제가 되었는지 확인 있다.

 

 

 

 

7. Reset current Branch to Here…

현재 브랜치를 커밋 시점으로 되돌린다. 

이때 옵션이 4가지가 있다. (Soft, Mixed, Hard, Keep)

 

 

 

1️⃣ soft reset (—soft)

변경 사항이 유지된다 (커밋만 삭제되고, 스테이징 영역 유지)

선택한 커밋으로 브랜치가 이동하지만, 변경 사항이 스테이징된 상태로 남아있다.

git reset --soft HEAD~1

 

 

이전 커밋으로 soft reset되어 변경사항이 스테이징된 상태로 남아있음

 

 

보통 soft reset의 전단계로 돌아가고 싶다면, 깃허브에서 pull받아오는 방법을 많이 사용한다.

나의 경우 테스트용 브랜치를 파뒀었다…

특정 브랜치를 삭제하고 싶을 경우에는 다른 브랜치로 이동한

git branch -d test/reset-current-branch-to-here

또는

git branch -D test/reset-current-branch-to-here

를 사용하면 된다. (위는 병합(merge)되어 브랜치를 삭제할 때, 아래는 병합되지 않은 상태에서의 강제 삭제)

 

 

스테이징이란?

 

Git이 커밋할 파일을 미리 저장해두는 영역

git add . 으로 스테이징을 수행

 

 

스테이징이 된 상태(git status로 확인)

Soft reset —> git add . 가 된 상태

 

 

 

 

2️⃣ mixed reset (—mixed)

기본 선택 옵션으로, 커밋만 삭제되고, 변경 사항은 워킹 디렉터리에 남음 (스테이징 해제됨) 

, 최근 커밋 내용이 다른 디렉터리에 남고 스테이징이 해제됨 

git reset --mixed HEAD~1

 

 

이전 커밋으로 mixed reset되어 변경사항이 스테이징이 해제된 상태로 남아있음 (스테이징 해제된 상태 = Changes 섹션에 파일이 있는 상태—> 워킹 디렉터리에는 변경사항이 남아있지만 git 스테이징 되지 않은 상태)

 

스테이징 안된상태(git status로 확인)

Mixed reset —> git add . 가 안 된 상태

 

 

 

3️⃣ hard reset (—hard)

커밋과 스테이징과 워킹 디렉터리 변경사항이 모두 삭제된다

특정 커밋으로 완전히. 과거로 되돌려버리기 때문에 이후 작성한 커밋 코드내용을 확인할 없으므로 신중히 사용해야한다.

git reset --hard HEAD~1

만약 실수로 hard reset을 사용했다면,

git reflog HEAD 이동 기록을 확인해야한다.

 

이전 커밋이 hard reset되어 스테이징, 이후 커밋으로 작성했던 코드내용 모두 남지 않음

 

 

 

 

 

 

4️⃣ keep reset (—keep)

커밋을 되돌리지만 현재 작업중인 변경사항은 유지된다.

관리되는 파일 (add) 변경되지 않은 파일만 되돌리고, 관리되지 않은(add하지 않은) 파일은 삭제되지 않음

git reset --keep HEAD~1

 

Smart reset 사용하면 다음과 같이 변경사항을 보존할 있다.

 

 

 

왼쪽부터 보존상태인(add)한 코드 내용이 있을 때,

보존상태가 아닌 코드 내용의 이전 커밋,

Hard reset시 적용되는 코드이다.

이를 확인하고 때에 따라 코드상태를 reset 있다. (1번쩨(left) 3번째(right) 중에서)

 

옵션 커밋 삭제 스테이징 해제 워킹 디렉터리 영향 언제 사용하는지
Soft (--soft) 유지됨 유지됨 마지막 커밋만 수정할
Mixed (--mixed) 해제됨 유지됨 커밋을 취소하고 다시 스테이징할
Hard (--hard) 해제됨 변경 사항도 삭제됨 완전히 되돌려야 (복구 불가)
Keep (--keep) 해제됨 변경된 파일 유지 되돌리지만 현재 작업은 유지하고 싶을