반응형

 


git에서 두 개의 브랜치를 병합할 때 사용하는 두 가지 방법이 있습니다.

1. git merge
2. git rebase


 


1. git merge


//1. master 브랜치로 이동
$git checkout master
//2. 병합할 브랜치를 master브랜치에 merge
$git merge [master에 병합할 브랜치 명]

//위 1,2를 한번에 표현 가능
$git merge [master에 병합할 브랜치 명] master
  • 병합을 하면 합쳐진 브랜치의 커밋 메시지가 중복으로 쌓이게 됩니다.
  • 커밋 순서를 바꾸지 않습니다.
  • 존재하는 브랜치가 변경되지 않습니다.
  • 새로운 merge commit을 생성합니다.
  • git merge --abort : 병합을 취소하는 명령어

 

 

  • 위 이미지는 Main 브랜치에 Feature 브랜치를 병합하는 과정을 나타냅니다.
  • 커밋 순서가 변경되지 않고, 기존 분기는 유지되는 모습을 확인할 수 있습니다.

 

 


1-2. git conflict

충돌 상황 발생


 

//merge 실행
$git merge [master에 병합할 브랜치 명]

//conflict 발생
CONFLICT (content): Merge conflict in [수정한 파일]
Automatic merge failed; fix conflicts and then commit the results.
  • 자동 merge가 실패했으니, 충돌 부분을 수정하고 결과를 다시 커밋 하라는 경고문이 노출됩니다.
  • 충돌이 발생한 이유는 두 브랜치에서 [수정한 파일]의 내용이 서로 다르기 때문입니다.
  • 이와 같이 같은 부분에 서로 다른 부분이 있을 경우, merge conflict가 발생할 수 있습니다.
  • 이를 해결하기 위해 충돌이 발생한 부분을 수정이 필요합니다.

 

//[수정한 파일] 내용 출력
//사용하는 툴이 있다면 툴을 사용하여 conflict가 발생한 부분 수정하여도 됨
//ex : intelliJ, eclipse, vscode 등

$ cat [수정한 파일]
1. 안녕하세요.
2. git merge 중
3. conflict 상황 입니다.
<<<<<<< HEAD
4. 오전에 작성하였습니다.
=======
4. 오후에 작성하였습니다.
>>>>>>>> [병합할 브랜치 명]
  • 위처럼 충돌이 일어난 부분은 <<<<<<<<  ======= 혹은, =======  <<<<<<<< 사이에 표시됩니다.
  • <<<<<<<< 과 ======= 사이에 표시된 내용은 merge를 실행한 브랜치에 있는 내용을 나타냅니다.(HEAD가 가리키고 있는 내용)
  • 반대로 ======= 과 <<<<<<<< 사이에 표시된 내용은 merge 하고자 하는 브랜치(즉, 병합할 브랜치 명)의 내용을 나타냅니다.
  • 이 표시들을 기반으로 원하는 것을 선택하여 수정을 마친 후 충돌이 일어난 파일을 커밋 해주면 merge가 완성됩니다.(위에 표시된 기호들을 없앤 후 커밋)

 

$ cat [수정한 파일]
1. 안녕하세요.
2. git merge 중
3. conflict 상황 입니다.
4. 오후에 작성하였습니다.

- 위와 같이 수정 완료 후

 

$git add [수정한 파일]
$git commit
[master 7bj1583] Merge branch '[병합할 브랜치 명]'

- 성공적으로 수정하였을 경우의 출력 메시지입니다.

 

$git branch -d [병합 완료 된 브랜치 명]

- 병합이 끝난 브랜치를 삭제 처리합니다.

 

 

 


2. git rebase


 

  • Feature 브랜치를 Main 브랜치에 병합을 나타내는 이미지 입니다.
  • 위 그림처럼 Feature 브랜치의 커밋은 Main 브랜치가 가지고 있던 기존의 커밋 뒤에 위치하게 됩니다.

 

//master에 rebase 할 브랜치로 이동
$git checkout [rebase 할 브랜치]
$git rebase master

//rebase 할 브랜치를 master 브랜치에 merge
$git checkout master
$git merge [rebase한 브랜치]
  • 병합을 하면 브랜치의 커밋 메시지가 시간 순서대로 합쳐집니다.
  • 히스토리를 깔끔하게 유지하기 위해 사용합니다.
  • 전체 브랜치를 마스터 브랜치 끝에 위치 시킵니다, 그렇기 때문에 master 브랜치의 기존의 마지막 커밋 뒤에 병합할 브랜치의 커밋들이 합쳐지게 하여 master 브랜치에 재배치(rebase) 하는 것을 말합니다.

 

rebase 하기 전

 

rebase 된 후

 

  • 즉, 위 그림처럼 master 브랜치의 m2 상태에서 다른 브랜치의 f1, f2 커밋을 재배치(rebase) 하면, 두 번째 사진과 같이 m2 이후에 f1, f2 이 재배치됩니다.

 

 


2-1. rebase 진행 과정


 

//feature 브랜치로 체크아웃한 상태
$git checkout feature

 

feature 브랜치로 체크아웃한 상태, head는 feature를 가리키고 있음

 

 

$git rebase master

 

master와 feature의 공통 조상이 되는 base 커밋부터 현재 브랜치까지의 변경 사항(▵1, ▵2)을 구해서 patch로 저장해 둠

 

 

head를 master로 변경

 

 

Applying f1 : head가 현재 가리키고 있는 m2에 변경사항 ▵1 을 적용하여 새로운 커밋 f1'을 생성

 

Applying f2 : f1'에 변경사항 ▵2 을 적용하여 새로운 커밋 f2'을 생성

 

feature가 f2'를 가리키도록 함

 

 

$git merge feature

 

feature를 master로 fast-forward merge 하여 완료

 

 


2-2. rebase 사용법


 

//수정할 커밋들의 리스트 출력
//git rebase -i [수정을 시작할 커밋의 이전 커밋] 형식으로 입력
$git rebase -i HEAD~4

//4개의 커밋 리스트 노출
hint: Waiting for your editor to close the file...
pick 907c451 commit1
pick 1a7c765 commit2
pick v07c952 commit3
pick 40jc438 commit4

//사용할수있는 명령어 리스트
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.

 

pick

-커밋을 사용하겠다는 의미, 이를 이용해 커밋의 순서를 바꿀 수 있고, 커밋의 해시값을 이용해 특정 커밋을 가져올 수 있습니다.

- rebase 명령어를 실행하면 기본적으로 pick으로 설정돼있기 때문에 아무것도 변경하지 않고 종료한다면, 커밋에 대하여 어떠한 변경도 일어나지 않게 됩니다.

- 위 코드에서 commit2와 commit3의 순서를 바꾼다면, 커밋 순서와 커밋 해시값까지 변경됩니다.

reword

- 커밋 메시지를 변경하는 명령어

- 커밋 메시지를 변경할 커밋 앞에 reword 명령으로 수정하고, 저장하면 해당 커밋의 메시지를 다시 작성하는 에디터 창이 열리게 됩니다.

- 커밋 메시지와 커밋의 해시값 또한 변경됩니다.

edit

- reword 명령어는 커밋 메시지만 변경하는 명령이라면, edit 명령어는 커밋 메시지뿐만 아니라 커밋의 작업 내용까지 변경할 수 있습니다.

- commit4라는 커밋을 edit으로 바꾸고 저장 후 종료하면, 변경할 커밋으로 checkout됨, 그 상태에서 변경 작업을 수행하면 됩니다.

- 그 후 변경사항을 저장하기 위해 아래와 같은 명령어 입력

//staged 상태 변경
$git add . 

//변경할 커밋메시지 입력
$git commit --amend -m "commit4-amend"

//rebase처리
$git rebase --continue

- 커밋 내용과 메시지 모두 변경됩니다.

 

squash

- squash 명령어는 해당 커밋을 이전 커밋과 합치는 명령어입니다.

pick 907c451 commit1
pick 1a7c765 commit2
squash v07c952 commit3
pick 40jc438 commit4

- commit3 커밋을 직전 커밋인 commit2 커밋과 합치기 위해 squash로 변경합니다.

- 저장 후 종료하면 커밋 메시지를 수정할 수 있는 에디터 창이 뜹니다.

- 합쳐질 커밋들의 메시지를 확인한 후 그대로 종료하면 아래와 같이 이전 커밋과 하나로 합쳐진 것을 볼 수 있습니다.

pick 907c451 commit1
pick 73dc735 commit2
pick 40jc438 commit4

 

 

fixup

- fixup 명령어는 squash와 동일하게 해당 커밋을 이전 커밋과 합치는 명령어이지만, 커밋 메시지는 합쳐지지 않습니다.

- 결과적으로 이전 커밋의 커밋 메시지만 남게 됩니다.

exec

- exec 명령어를 이용하면, 각각의 커밋이 적용된 후 실행할 shell 명령어를 지정할 수 있습니다.

- 각각의 커밋이 실행된다는 것을 확인하기 위해 중간중간에 메시지를 넣는 행위입니다.

drop

- drop 명령어는 커밋 히스토리에서 커밋을 삭제합니다.

- drop으로 변경 후 저장하면, 해당 커밋이 drop 되는 것을 확인 가능합니다.

pick 907c451 commit1
drop 73dc735 commit2
pick 40jc438 commit4

 

 


2-3. rebase 시 유의사항


- 이전의 커밋 히스토리를 변경하기 때문에 항상 주의가 필요합니다.

- 만약 이미 Github과 같은 원격 저장소에 push까지 한 커밋이라면, 변경한 커밋들은 원격 저장소에 push 되지 않을 것입니다.

- 이때 $git push --force, $git push -f 명령으로 강제로 원격 저장소에 커밋 히스토리를 덮어쓸 수 있습니다.

- 만약 이전에 push 한 커밋들을 다른 개발자들과 공유하고 있었다면, 커밋 히스토리의 불일치가 발생해 git이 꼬이는 현상이 발생할 수 있습니다.

 

 

출처: https://hajoung56.tistory.com/5

반응형
반응형

정기적으로 깃 계정 비밀번호를 변경해주는데, 소스트리에서 비밀번호 일치하지 않는다고 에러를 띄웠다.
여러가지 방법이 있겠지만 나는 이렇게 함.
맥 OS X 를 기준으로 하였다.

SourceTree 설치된 경로로 이동. (파인더에서 cmd + shift + g)
~/Library/Application Support/SourceTree
아이디@STA~ 를 지워준다.
그리고 소스트리에서 pull push 이런거 하려고 하면 다시 비밀번호 물어봄.

출처 : blog.naver.com/PostView.nhn?blogId=amabile29&logNo=221212585311&categoryNo=0&parentCategoryNo=0&viewDate=&currentPage=1&postListTopCurrentPage=1&from=postView

반응형
반응형

github에 레포지터리를 생성하지 않고 시작한 경우입니다.

레포에는 아무 파일이 존재하지 않아야합니다.

 

1. github에 새로운 저장소(레포지터리)를 만듭니다.

 

2. 터미널을 열어줍니다.

 

3. 자신이 git에 올리고 싶은 root 폴더로 이동합니다.

 

4. 해당 폴더의 깃을 초기화 하여 줍니다.

$ git init

 

5. commit을 합니다.

$ git add .

$ git commit -m "First Commit"

 

6. remote repository를 등록합니다.

※ 깃헙 레포 url은 웹에서 해당 레포를 들어가시면 확인이 가능합니다.

$ git remote add origin [ github repo URL ]

$ git push -u origin master

 

반응형
반응형

.gitignore will prevent untracked files from being added (without an add -f) to the set of files tracked by git, however git will continue to track any files that are already being tracked.

To stop tracking a file you need to remove it from the index. This can be achieved with this command.

구글번역 : .gitignore는 추적되지 않은 파일이 git에 의해 추적 된 파일 세트에 추가 (-f없이)되는 것을 방지하지만, git은 이미 추적중인 파일을 계속 추적합니다. 파일 추적을 중지하려면 색인에서 파일을 제거해야합니다. 이것은이 명령으로 달성 할 수 있습니다.

git rm --cached <file>

 

If you want to remove a whole folder, you need to remove all files in it recursively.

구글번역 : 전체 폴더를 제거하려면 해당 폴더의 모든 파일을 재귀 적으로 제거해야합니다.

 

git rm -r --cached <folder>

The removal of the file from the head revision will happen on the next commit.

WARNING: While this will not remove the physical file from your local, it will remove the files from other developers machines on next git pull.

구글 번역 : 헤드 개정에서 파일 제거는 다음 커밋에서 발생합니다.

경고 : 로컬에서 실제 파일을 제거하지는 않지만 다음 git pull에서 다른 개발자 컴퓨터에서 파일을 제거합니다.

 

출처 : https://stackoverflow.com/questions/1274057/how-to-make-git-forget-about-a-file-that-was-tracked-but-is-now-in-gitignore

반응형

+ Recent posts