Git cherry-pick, rebase

|

cherry-pick과 rebase에 대해 공부한 내용을 정리해 봅니다.

위 두 명령어는 누군가와 협업하여 소스를 관리할 때 유용한 명령어로 남의 작업과 나의 작업을 합치게 될 때 사용하게 됩니다.

cherry-pick

특정 commit에 대한 이력을 가져옵니다.

status1

위와 같은 상황에서 work1 branch에 master에 commit된 m3가 필요할 경우 아래와 같이 cherry-pick 명령어를 통해 추가할 수 있습니다.

[master]
$ git log --pretty=format:"%h %s"
fa16562 m4
94c79c0 m3
3654326 m2
f56f92a m1


[work1]
$ git cherry-pick 94c79c0

status2

이때 cherry-pick으로 가져온 m3는 master의 m3와는 별개의 commit으로 work1 과 master를 merge 할 경우 아래와 같이 별도 commit으로 보이게 됩니다.

status3

위와 같이 cherry-pick을 쓰는 경우를 예로 들면
여럿이 작업중 누군가가 공통 UTIL을 만들어 배포할 경우 해당 UTIL을 자신의 branch에 추가하는등의 작업과 같이 사용하게 됩니다.

rebase

branch를 master(또는 다른 branch)로 합치기 전에 이력을 보기 좋게 만드는데 사용하게 됩니다.

status4

위와 같이 다수의 branch에서 작업하다가 merge하는 경우 서로 이력이 꼬여 보기 좋지 않을 때가 있습니다.

status5

이 때 각 branch에서 rebase를 통해 commit 이력을 끌어오면 아래와 같이 예쁘게 이력을 정렬 가능합니다.

[work1]
$ git rebase master
$ git log --pretty=format:"%h %s"
277030f w2
4d72d03 w1
4283fad m3
08e8d8d m2
4820c18 m1    

status6

work1의 이력에 위와 같이 master의 m2,m3가 commit이력에 추가된 것을 볼 수 있습니다. git log를 통해서 commit된 hash값을 보아도 같은 값인것으로 보아 work1의 branch 생성 시점이 master의 현재 HEAD부분으로 이동했다고 봐도 무방할것 같습니다.

$ git merge --no-ff work1

위와 같이 merge하게 되면 아래 그림과 같이 예쁘게 merge가 됩니다.

status7

work2도 같은 방식으로 merge하면 최종적으로 아래와 같이 보기 좋게 merge됩니다.

status8

Git 저장소 생성(init) 및 복사(clone)

|

git init

저장소에 필요한 Seleton파일을 가지고 있는 “.git”이라는 하위 디렉토리를 만들어줍니다.
※ 아직 프로젝트의 어떤한 파일도 관리하지 않는 상태이며 commit, add등의 명령어로 파일을 추가해야합니다.

$ git init        // 현재 디렉토리에 .git 폴더를 생성합니다.
$ git init work1  // ./work1 디렉토리에 .git 폴더를 생성합니다.

–bare

Bare저장소를 생성합니다.
Bare저장소는 워킹디렉토리가 없는 저장소로 디렉토리는 관례에 따라 .git확장자로 끝납니다.

$ git init --bare <project_name>.git    

git clone –bare (src-project) (bare-project)

이미 git init을 통해 이미 관리되고 있는 프로젝트의 Bare저장소로 만들고 싶을 경우 아래와 같이 사용할 수 있습니다.

$ git clone --bare test test_bare.git
$ ls ./test_bare
config  description  HEAD  hooks/  info/  objects/  packed-refs  refs/

git clone (path) [project-name]

Bare저장소로부터 프로젝트를 로컬에 복사하고 싶을 경우 아래와 같이 사용할 수 있습니다.
(path)는 파일 경로도 가능하고 URL경로도 가능합니다.

$ git clone ./test_bare.git test
$ git clone file://d/work/test_bare.git test
$ git clone https://github.com/jistol/jistol.github.io jistol-project
$ git clone git://127.0.0.1:7777/jistol/jistol.github.io jistol-project
$ git clone ssh://127.0.0.1:22/jistol/jistol.github.io jistol-project

git clone -b (branch-name) (path) [project-name]

Bare저장소의 특정 branch를 로컬에 복사하고 싶을 경우 아래와 같이 사용할 수 있습니다.

$ git clone -b work1 file://d/work/test_bare.git localwork1

Git branch 주요 명령어 정리

|

git branch명령은 branch 생성및 제거, 확인등의 기능을 하는 명령어로 주요 명령어만 요약하였습니다.
자세한 내용은 git-scm Git-브랜치-브랜치-관리에서 확인하세요.

git branch [-l]

로컬 branch 정보를 보여줍니다. (-l 옵션은 생략가능)

$ git branch
* master
  work1

git branch -v

로컬 branch의 정보를 마지막 커밋 내역과 함께 보여줍니다.

$ git branch -v
* master   4bbc62f commit message 'm1'
  work1    fe7f049 commit message 'w1'
  work_new 4bbc62f commit message 'work_new1'

git branch -r

리모트 저장소의 branch 정보를 보여줍니다.

$ git branch -r
  origin/master
  origin/work1

git branch -a

로컬/리모트 저장소의 모든 branch 정보를 보여줍니다.

$ git branch -a
* master
  work1
  remotes/origin/master
  remotes/origin/work1

git branch (이름)

로컬에 새로운 branch를 생성합니다.

$ git branch work_new
$ git branch -a
* master
  work1
  work_new
  remotes/origin/master
  remotes/origin/work1

※ 생성과 동시에 해당 branch로 이동하려면 아래 명령어를 사용합니다.

$ git checkout -b work2

※ 원격에 있는 branch를 가져오려면 아래 명령어를 사용합니다.

[특정이름 지정시]
$ git checkout -b work2 origin/work2      
[원격 branch 이름을 그대로 사용할 경우]
$ git checkout -t origin/work2

git branch (–merged | –no-merged)

--merged는 이미 merge된 branch를 표시해주고 --no-merged는 아직 merge가 되지 않은 branch만 표시합니다.
--merged에 branch 목록 이미 merge되었기 때문에 *가 표시되지 않은 branch는 삭제 가능합니다.

$ git branch --merged
* master
  work_new
  work_old

$ git branch --no-merged
  work1
  work2

git branch -d (branch 이름)

branch를 삭제합니다. 아직 merge하지 않은 커밋을 담고 있는 경우 삭제되지 않습니다.(강제종료 옵션 -D으로만 삭제 가능)

$ git branch -d work3
error: The branch 'work3' is not fully merged.
If you are sure you want to delete it, run 'git branch -D work3'.

$ git branch -d work_new
Deleted branch work_new (was 4bbc62f).

git branch -m (변경할 branch이름) (변경될 branch이름)

A 브랜치를 B 브랜치로 변경합니다.

$ git branch -v
* master   4bbc62f m1
  work2    c728ddc w2
  work_old 4bbc62f m1

$ git branch -m work2 work3

$ git branch -v
* master   4bbc62f m1
  work3    c728ddc w2
  work_old 4bbc62f m1

※ -M 옵션을 사용할 경우 기존에 동일한 이름의 branch가 있더라도 덮어씁니다.

Git Remote 주요 명령어 정리

|

git remote명령은 프로젝트의 리모트 저장소를 관리하는 명령어로 주요 명령어만 요약하였습니다.
자세한 내용은 git-scm Git-브랜치-리모트-브랜치에서 확인하세요.

git remote

등록된 리모트 저장소 이름만 보여줍니다.

$ git remote
origin

git remote -v

등록된 저장소 이름과 URL을 표시합니다.

$ git remote -v
origin  D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git (fetch)
origin  D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git (push)

git remote add (리모트이름) (경로)

새 리모트를 추가합니다. (경로)영역에는 URL이나 파일경로를 넣을수 있습니다.

$ git remote add jistol https://github.com/jisto.github.io
$ git remote add origin D:/dropbox/Dropbox/jekyll/git-source/test.git
$ git remote -v
jistol  https://github.com/jisto.github.io (fetch)
jistol  https://github.com/jisto.github.io (push)
origin  D:/dropbox/Dropbox/jekyll/git-source/test.git (fetch)
origin  D:/dropbox/Dropbox/jekyll/git-source/test.git (push)

git remote show (리모트이름)

모든 리모트 경로의 branch와 정보를 표시합니다.

$ git remote show origin
* remote origin
  Fetch URL: D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git
  Push  URL: D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git
  HEAD branch: master
  Remote branches:
    master tracked
    work1  tracked
  Local branches configured for 'git pull':
    master merges with remote master
    work1  merges with remote work1
  Local refs configured for 'git push':
    master pushes to master (up to date)
    work1  pushes to work1  (up to date)

git remote rm (리모트이름)

리모트 경로를 제거합니다.

$ git remote -v
jistol  https://github.com/jistol/jistol.github.git (fetch)
jistol  https://github.com/jistol/jistol.github.git (push)
origin  D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git (fetch)
origin  D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git (push)

$ git remote rm jistol

$ git remote -v
origin  D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git (fetch)
origin  D:/dropbox/Dropbox/jekyll/git-work/user1/../../git-source/test.git (push)

Git GUI 툴 추천 - GitKraken

|

Git에 대해 공부하면서 대부분 bash에서 실행했으나 전체 commit tree를 보기 위해서는 GUI툴의 도움을 받아야 했는데 처음 사용한 툴이 Atlassian의 SourceTree였습니다. 사용하다보니 무한 로딩에 짜증나고 종종 먹통이 되며 특히 reset명령을 하면 갱신이 멈춰버렸습니다.
그런 와중에 다른 무료툴을 살펴보다 발견한것이 GitKraken입니다.

capture1

이 툴을 추천하는 이유는 아래와 같습니다.

  1. 갱신 속도가 빠릅니다.
    SourceTree에 비해 엄청나게 이력 갱신이 빠릅니다. 로딩바도 없고 신세계!!

  2. 멀티 저장소/Branch 선택 기능 제공 저장소 선택 가능하고
    capture2
    저장소별 branch도 선택 가능합니다.
    capture3

  3. Drag and Drop을 통한 Merge & Rebase
    capture4
    capture5
    capture6

  4. 간편한 Undo / Redo 기능
    capture7

  5. Dark계열의 디자인
    IntelliJ Darcula Theme, Atom과 나란히 쓰기 좋네요~
    어두운 계열 에디터 쓰기 좋아하시는 분들에게 추천합니다. capture8

  6. 그 외 웬만한 기능을 다 지원(Pull, Push, Branch, 변경소스 확인 …) capture9

무료버전외에 돈주고 유료로도 사용 가능하지만 충분히 무료로도 쓰기 편합니다.