git-branch에서 rebase하는 방법

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
이 포스팅에서는 branch rebase에 대해 설명합니다.

주요 용어 : push clone fetch pull rebase


Rebase? - 아직 수정 중

rebase또한 브랜치들을 merge하는 방법이다.

그러나 기본 merge, 즉 3-way 머지는 새로운 커밋을 만들었는데, 그래서 조금 복잡했는데 굳이 그러지 않아도 되는 경우가 있따.

합치는 과정이 없이 1자로 가는 로그를 만들어줄 수 있어

C2를 기반으로 하고 있던 C4(Experiment)를 C3(master)도 받고 C3의 뒤로 가도록 하는 방법은 git rebase master (experiment가 현재 브랜치인 경우로 설정. 그러면 현재 브랜치를 master 뒤에 놓도록 하는 명령어) -> master뒤에 experment 브랜치가 존재한다.

만약 오류가 뜬다면, vim을 통해 수정하고 git add -A, git rebase continue 하면 된다.

시점만 갈라지는 경우에는 리베이스를 하는게 좋다.

작업한 내용의 기록: merge, rebase: 옆으로 굳이 안갈라져도 되는 경우 그리고 로컬에서만 해야하고, 푸시한 커밋에서 하면 안된다. 이미 공개 저장소에 푸시한 커밋을 리베이스하지 마라 -> 리베이스하면 기존 커밋을 없애기 때문에, 다른 사람의 가지는 복잡해진다.

그래서 리베이스는 푸시한 커밋은 변경하면 안돈다.!

리베이스 충돌 해결 feature branch workflow

현재 브랜치를 이 브랜치로 옮긴다 $ git push -u origin yh-feature 알아서 완성시켜준다

Forking workflow 중앙저장소는 하나, 거기서 중앙저장소를 기반으로 한 개인 저장소를 다운을 받고 결과적으로 리모트 저장소는 3개

오픈소스: 여러며으이 개발자가 모여 코드를 만들어서 반영을 시키는데 그 코드를 관리하는 컨트리뷰터-> 괜찮다고 생각하면 머지를 시켜주고 그렇게 되면 콜라보레이터 안에 내가 컨트리뷰터가 되는것

포크 뜬 브랜치는 깃에만 있지 로컬에는 없어

git-branch에서 merge하는 방법

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
이 포스팅에서는 branch merge에 대해 설명합니다.


merge?

작업중인 웹사이트가 잇는데, 새로운 이슈가 생겨 수정사항을 처리할 때, 마스터 브랜치의 내용은 변경되지 않았으면 해서 하는 행동이 새로운 브랜치를 만드는것이다.

따라서, 작업을 진행하던 중에, 작업하던 브랜치를 두고 다른 마스터 브랜치로 가서 새로운 브랜치를 만들고 작업을 한다음 그게 끝난 뒤 merge를 하고 다시 원래 작업으로 돌아오는 것을 기본으로 한다.

운영브랜치 이름은 보통 master(운영이름)라고 하고, 사실 우리가 부르는 마스터는 그 의미 자체가 특별한건 아니고 그냥 이름이 마스터인 것이다.

따라서 우리는 이슈를 처리할 새로운 브랜치를 만들어 여기에서 이제 issue를 처리할 것이다.

그 의미는 곧, masterissue가 가리키고 있는 commit이 다르다는 것을 의미한다.

(master) echo c1 >> C1.html
git add C1.html
git commit -m 'First!'

(master) echo c2 >> C2.html
git add C2.html
git commit -m 'Second!'

(master) echo c3 >> C3.html
git add C3.html
git commit -m 'Third!'

git branch iss53
git checkout iss53

(iss53) vi C3.html
# C3.html의 내용을 수정하고
git add C3.html
git commit -m 'C3의 내용을 수정했다'

git log --oneline --all --graph
#이를 통해 master와 iss53가 가리키는 브랜치를 확인할 수 있다.

git checkout master
# HEAD의 이동을 파악하고

# master 브랜치에서 다시 하나의 새로운 브랜치를 생성한다

git branch hotfix
# 그리고 새로 만든 브랜치에 checkout한다.
git checkout hotfix

git branch -b <branch 이름>

vi C2.html
# 메시지 내용 수정 뒤

git add C2.html
git commit -m 'C2의 내용도 수정을 했다!'

# 이때 새로만든 hotfix라는 브랜치를 master에 합쳐야 하는데,
# 이 방법은 master 브랜치로 돌아가 새로 만든 hotfix 브랜치와 합치하겠다고 명령어를 주는 것이다.

git checkout master
git merge hotfix

git log --oneline --all --graph
# 여기서 나오는 Fast forward는 앞으로 옮겨졌다는 뜻이다.
git branch -d hotfix
# 이제 hotfix 파일을 merge했으니 필요없어진 이 브랜치는 삭제한다.

이와 같은 방식으로 이전에 보고 있던 이슈에 대해서도 같게 처리해준다

git checkout iss53

vi C3.html
git add C3.html
git commit -m 'C3를 다시 수정했다'

git checkout master
git merge iss53

git branch -d iss53

merge commit?

현재 마스터는 브랜치의 조상이 아니기 때문에 커밋 두개와 공통 조상 하나가 있는 상태인데 이 세가지 커밋을 이용해서 하나의 컷을 만드는 즉 merge commit이라고 한다.

ide: 통합개발환경 우리가 어떤 코드를 작성을 하고 작성한 코드를 확인하고 실행가능한 파일로 만들어주는 역할을 예전엔 따로 했지만, 이를 한번에 해주는 것 -> 파이참 등…

conflict가 일어나는 이유 두 파일을 합칠 때, 수정된 내용이 컴퓨터도 인지하기 어려울 정도로 너무 같은 부분이 합쳐졌다고 생각하면 충돌이 생긴다.

그러면 다시 추가를 하고 수정을 하라고 뜬다. 충돌이 뜨지 않은 경우에는 위에서처럼 정상적으로 merge가 됐고, 필요없어진 브랜치는 삭제하면 된다.

여튼, 충돌이 일어나는 경우로 다시 돌아오자면

일반적으로는 auto merging이 되지만 충돌이 자주 일어나기도 한다.

# 새로운 브랜치인 iss54를 만들고 그 안에 맨 마지막 줄에 커밋메시지를 작성하고
# 브랜치를 다시 마스터로 옮긴 뒤 마스터의 마지막 줄에도 커밋메시지를 남긴다.

git branch iss54
git checkout iss54

vi C3.html
git add C3.html
git commit -m 'finish [iss54]'
# 어짜피 브랜치는 사라지기에 어떤 브랜치였는지를 적어주면 좋다.

git checkout master
vi C3.html
git add C3.html
git commit -m 'master finished [master]'

git merge iss54

라고 하면

Auto-merging C3.html
CONFLICT (content): Merge conflict in C3.html
Automatic merge failed; fix conflicts and then commit the result.

이렇게 나올 것이다.

즉 같은 라인에 양쪽이 커밋 메시지를 남기는 경우 merge conflict가 일어난다.

이때 우리는

git status

상태를 확인해보면

On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   C3.html

C3.html 파일이 공통적으로 수정되었다는 것을 확인했으니

vi C3.html

여기서 원하는 commit만을 남기고 dd를 통해 삭제한다.

다시

git status

해도

On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   C3.html

변화는 없지만

git add C3.html
git status

git add를 실행하고 나면

On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

	modified:   C3.html

git commit
git log --oneline --all --graph
git branch -d iss54

이렇게 우리는 branch merge가 가능해졌다!

git-branch의 workflow 이해하기 - push, fetch, remote repository

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
이 포스팅에서는 branch Workflow에 대해 설명합니다.

주요 용어 : push clone fetch pull


Branch Workflow?

브랜치를 만들고 merge하는 것을 어디에 써먹어야 하는지 알아보자

롱러닝 브런치 git은 꼼꼼하게 3-way-merge를 사용하기 때문에 장기간에 걸쳐 한 브랜치를 다른 브랜치와 여러 번 merge하는것이 쉬운편이다. 그래서 개발 과정에서 필요한 용도에 따라 브랜치를 만들어 두고 계속 사용할 수 있다. 그리고 정기적으로 브랜치를 다른 브랜치로 merge한다.

이러한 접근법에 따라서 git개발자가 많이 선호하는 워크플로가 있는데, 그게 바로 long-running workflow이다.

이는, 배포했거나 배포할 코드, 즉 실제 운영환경에 나가는코드는 master 브랜치에 두고, 개발을 진행하고 안정화하는 브랜치는 develop이나 next라는 이름을 추가로 만들어 사용된다. 이러한 브랜치들은 언젠가 안정 상태가 되겠지만, 항상 안정상태를 유지해야하는 것은 아니다.

테스트를 거쳐 안정적이라고 판단되면 master브랜치에 merge한다. 그리고 현재 우리가 이슈를 다르고 있는 브랜치는 iss53브랜치로 이 같은 브랜치 또한 해당 토픽을 처리하고 테스트해서 버그가 없고 안정적이게 된다면 merge된다.

이제 remote branch를 만들어보도록 하자. (local이 아님을 반드시 기억하자)

우선 본인의 git hub에 들어가 remote repository를 만들도록 한다.

그리고 zsh에서

mkdir git-remotebranch
take git-remotebranch

git init

# http:// 부터의 주소는 본인의 리모트 저장소 주소를 의미한다.
git remote add http://~
# 리모트 저장소를 추가하기 위해서는 add를 사용하는데
# 앞에 있는 것은 우리가 별칭으로 사용할 리모트 저장소의 이름이 되고
# 뒤에 있는 것은 리모트 저장소의 주소가 된다.

git remote -v

하고나면

origin	https://github.com/zehye/Git-Remote-breanch.git (fetch)
origin	https://github.com/zehye/Git-Remote-breanch.git (push)

이는 이 저장소에 연결되어 있는 리모트 저장소를 나타내는 것이다.

일반적으로 리모트브랜치 이름은 (remote)/(branch) 형식으로 나타난다. 예로들어 리모트 저장소의 originmaster브랜치를 보고 싶다면 origin/master라는 이름으로 브랜치를 확인하면 된다.

다른 팀원과 함께 어떤 이슈를 구현할 때 그 팀원이 iss53이라는 브랜치를 서버로 push했고 나 또한 로컬에 iss53이라는 브랜치가 있다고 가정하자면, 이때 서버의 iss53 브랜치가 가리키는 컷은 로컬에서 origin/iss53이 가리키는 커밋이다.

예로 들어 git.ourcompany.com이라는 git 서버가 있고 이 서버의 저장소를 하나 clone하면 git은 자동으로 origin이라는 이름을 붙인다. origin으로부터 저장소 데이터를 모두 내려받고 master브랜치를 가리키는 포인터를 만든다. 이 포인터는 origin/master를 가리키게 하고 이제 이 master브랜치에서 작업을 시작할 수 있다.

git push origin master

# clone하는 방법은 -> git clone 디렉토리 주소
git clone ~

이렇게 clone하게 되면 cd, remote-v, branch-v, git log 모두 다 동일하게 나온다. 그리고 위에서 말했듯 클론 받은 저장소가 origin 으로 된다.

이때 클론 받은 사람이 파일을 수정해본다.

vi README.md
git add README.me
git commit -m '~'

이를 두개 만들어서 log를 통해 파악해보면 HEAD/masterorigin/master가 다르게 들어가 있음을 볼 수 있다.

이때 master에 origin/master의 내용을 보여주고 싶다면

git push origin master

git log에 들어가 확인해보면 한 곳에 브랜치가 다 모여있다.

그런데 이는 origin 저장소에 변경된 내용을 로컬 워킹 디렉토리에 변경사항만 가져온 것으로 바로 적용이 되는 것은 아니다.

이를 합치려면 (내가 만든 커밋과 상대가 만든 커밋을 합쳐야 하니까)

그때

git fetch origin

근데 이때

git merge origin/master

하려고 하면 충돌이 생기고 그 충돌은 앞에서 했던 것처럼 해결한 뒤

vi ~

git add ~
git commit -m '~'

git push origin master

해결!

참고 remote repository 이름 바꾸는 방법

git remote rename ~

remote repository 삭제하는 방법

git remote remove ~

근데 저장소를 삭제한다는 의미는 로컬에서의 연결만 지워지는 것이지 그 저장소는 그대로 남아있다.

git-branch 이해하기

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
이 포스팅에서는 ‘branch’에 대해 설명합니다.


Branch?

일반적으로 운영환경은 프로그램에 의해 돌아가는 서비스라고 하는데, 즉 실제 유저가 사용하고 있는 프로그램 상태를 의미한다.

그 운영환경에 사용되는 소스코드들이 존재하는데, 우리는 해당 소스코드를 마음대로 고쳐쓸 수는 없다. 왜냐하면 아직 수정된 코드에 버그가 있는지 확인하지도 않은 상태에서 운영환겨에 그대로 적용이 된다면, 실제 사용자가 사용할 때 바로 에러가 발생하게 되니까!

따라서 우리는 운영코드는 그대로 두고, 소스코드를 통째로 따와 그 곳에서 개발을 하고 실험을 한 뒤, 더이상 안정화가 되었다고 생각이 들었을 때, 변경사항을 운영코드에 올리도록 한다.

그런데 사실, 어떤 프로젝트를 개발한다고 했을때, 여러명의 개발자들이 자신만의 독자적인 개발을 진행하는데, 단 하나의 저장소만을 사용한다고 하면 너무 번거롭기 때문에 개발자들이 나눠서 개발을 하다가 나중에 합치는 활동을 하는데

그 과정이 마치 여러 갈래로 나뉘는 것처럼 보여 그것을 branch브랜치라고 한다.

이러한 branchgitcommit 사이를 가볍게 이동할 수 있는 어떤 포인터같은 것으로 브랜치는 특정 커밋을 가리키는 역할만 한다.

이러한 git에서는 master라는 브랜치 하나를 기본적으로 만드는데, 이 같이 master브랜치를 가지고 있는 이유는 이 브랜치가 가리키는 어떤 스냅샷, 즉 시점에 맞게 working directory를 보여주기 때문이다.

1. branch 만들기

git branch testing
# testing은 branch의 이름이다.

이때 HEAD는 master와 testing 을 가리키고 있고 그 의미는 즉슨, 같은 commit을 가리키고 있음을 뜻한다.

HEAD는 지금 작업중인 branch가 무엇인지를 알려준다. 이 헤드 포인터는 지금 작업하고 있는 local branch를 의미한다. 즉 zsh에서 master라고 표시되어 있는 이유는 지금 HEAD가 어디에 위치하고 있는지를 바로 보여주는 것이다.

1-1. 브랜치 위치 확인하기

git branch -v

이떄 git branch명령은 새로운 브랜치를 만들기는 하지만, HEAD를 옮기지는 않는다.

1-2. 브랜치 이동하기

git checkout testing

이는 master에 있던 브랜치를 testing로 옮긴다.

cd ~/
mkdir branch
cd branch
git init

git status
(no commit yet)

echo README > README
echo test.rb > test.rb
echo LICENSE > LICENSE

git add README test.rb LICENSE
git commit -m 'The initial commit of my project'

echo 'change!!!' > test.rb
Git add test.rb
git commit -m 'made a change!'

git log --oneline

testingmaster가 향하는 위치가 다름을 파악할 수 있다.

여기서 잠깐 HEAD, tag, branch는 모두 커밋을 가리키는 기능은 전부 있다.

우선, tag는 딱 한개의 commit만을 가지는 것이고, HEAD는 워킹디렉토리가 어떤 스냅샷을 보여줄거냐를 중점으로 둔다. 근데 branch는 작업을 나눠서 하고 싶을 때 브랜치는 가리키는 커밋으로 가서 작업을 하는 것이다. 즉 남기는 커밋마다 브랜치는 이동이 가능하다.

우리가 어떤 커밋을 만드냐에 따라 브랜치는 그 커밋을 계속 따라간다.

master는 운영되고 있는 코드라고 하고, 새로운 코드를 만들고 싶어서 testing branch를 만들어 거기서 작업을 하면 브랜치는 계속 갈려 나아가는데 이 작업에 만약 branch가 아닌 tag를 붙여서 작업을 한다는 것은 아예 의미가 없다.

태그는 태그에 헤드를 가져다대는것이 그 자체가 불가능하다고 생각하면 된다. 물론 가능은 한데, 다음 작업을 할때 같이 이동을 한다는 것 자체가 없다.

git 버전관리 (VCS)

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
이 포스팅에서는 버전관리(VCS)에 대해 알아보며, 로컬 버전 관리(RCS)와 중앙 집중식 버전관리(CVCS), 분산 버전 관리 (DVCS)에 대해 설명합니다.


버전관리란?

버전관리시스템 (VCS, version control system)은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템을 의미한다.

즉, VCS를 사용하면 각 파일을 이전 상태로 되돌릴 수 있고, 프로젝트를 통째로 이전 상태로 되돌릴 수 있으며, 시간에 따라 수정내용을 비교할 수 있다. 더 나아가 누가 문제를 일으켰는지 추적이 가능하고 누가, 언제, 어떻게 만들어낸 이슈인지도 알 수 있다.

로컬 버전 관리 시스템

RCS(Revision control system)는 기본적으로 Patch set을 관리한다.

Patch set은 파일에서 변경되는 부분으로 이 Patch set은 특별한 형식의 파일을 저장한다. 그리고 일련의 Patch set을 적용해 모든 파일을 특정 시점으로 되돌릴 수 있다.

중앙 집중식 버전 관리 시스템

CVCS(Central VCS)는 프로젝트를 진행하는 중 다른 개발자와 함께 작업하는 경우 생기는 문제를 해결하기 위해 개발됐다. CVCSRCS에 비해 장점이 많다. 모두 누가 무엇을 하고 있는 지 알 수 있으며, 관리자는 누가 무엇을 할 지 꼼꼼하게 관리할 수 있다.

그러나 가장 큰 결점이 있다.

가장 대표적인 것은 중앙 서버에 발생한 문제다. 만약 서버가 한시간동안 다운되면 그동안 아무도 다른 사람과 협업할 수 없고 사람들이 하는 일을 백업할 방법도 없다. 그리고 중앙 데이터 베이스가 잇는 하드디스크에 문제가 생기면 프로젝트의 모든 히스토리를 잃는 다.

물론 사람마다 하나씩 가진 스냅샷은 괜찮다.

분산 버전 관리 시스템

DVCS(Distributed VCS)는 단순히 파일의 마지막 스냅샷을 checkout하지 않는다.

그냥 저장소 전부를 복제한다.

서버에 문제가 생기면 이 복제물로 다시 작업을 시작할 수 있고 클라이언트 중 아무거나 골라도 서버를 복원할 수 있다. 모든 checkout은 모든 데이터를 가진 진정한 백업이다.

게다가 대부분의 DVCS환경에서는 리모트 저장소가 존재한다.

그래서 사람들은 동시에 다양한 그룹과 다양한 방법으로 협업할 수 있다.

다음 포스팅에서는 git과 관련된 용어 정리를 할 것이다.