개발/GIT

[GIT] Repositories and Branches

Leedo1982 2021. 2. 22. 12:52

How to get a Git repository

repository를 얻는 가장 좋은 방법은 git-clone를 사용해 기존 저장소의 사본을 다운로드 하는 것이다.

 $ git clone git://git.kernel.org/pub/scm/git/git.git

대규모 프로젝트의경우 시간이 많이 걸리지만 한번만 복제하면 된다.

How to check out a different version of a project

git 는 파일의 컬렉션 기록을 저장하는 최고의 도구라고 생각한다.
단일 git저장소는 여러 브랜치의 개발을 추적한다
각 브런치의 마지막 commit 을 head 의 리스트 목록을 유지합니다.
git-branch 명령은 브런치 헤드의 리스트를 보여준다.

 $ git branch
 * master

대부분의 브런치는 tags 도 사용한다. 태그는 head 처럼, 프로젝트 기록의 참조이면, git-tag 명령을 통해 리스트를 할 수 있다.

 $ git tag -l
 v2.6.11
 v2.6.11-tree
 v2.6.12
 v2.6.12-rc2
 v2.6.12-rc3
 v2.6.12-rc4
 v2.6.12-rc5
 v2.6.12-rc6
 v2.6.13
 ...

tag 는 항상 프로젝트의 같은 버전을 보고 있습니다. 합니다. 반면 head 는 개발이 진행된에 따라 전진할 것이다.
git-switch 명령을 통해, 이 버전 중 하나로 새로운 브런치를 만들수 있다.
(git version > 2.23 )

 $ git switch -c new v2.6.13

명령을 실행하면 branch 가 생성된다.

 $ git branch
   master
 * new

특정 태그 버전을 보기로 결정했다면, 강제로 버전을 바라보게 할 수 있다.

 $ git reset --hard v2.6.17

현재 branch 의 head 가 특정지점에 대한 유일한 참조인 경우 해당 브런치를 재설정하면 이전 지점을 찾을 방법이 없을 수 있다.

Understanding History: Commits

프로젝트의 기록의 모든 변경은 commit 로 표시 된다.
git-show 는 가장 최근 커밋을 보여준다.

$ git show
commit 17cf781661e6d38f737f15f53ab552f1e95960d7
Author: Linus Torvalds <torvalds@ppc970.osdl.org.(none)>
Date:   Tue Apr 19 14:11:06 2005 -0700

    Remove duplicate getenv(DB_ENVIRONMENT) call

    Noted by Tony Luck.

diff --git a/init-db.c b/init-db.c
index 65898fa..b002dc6 100644
--- a/init-db.c
+++ b/init-db.c
@@ -7,7 +7,7 @@

 int main(int argc, char **argv)
 {
-    char *sha1_dir = getenv(DB_ENVIRONMENT), *path;
+    char *sha1_dir, *path;
     int len, i;

     if (mkdir(".git", 0755) < 0) {

첫번째 줄에 commit 의 40자리 16진수 ID(called "object name" or "SHA-1 id")가 있다.
객체의 이름은 해시로 계산되기 때문에 커밋의 내요ㅕㅇ을 확인하면 커밋이 변경 될 수 없음을 보장한다.

Understanding history: commits, parents, and reachability

모든 commit 는 parent commit 를 가지고 있다. 이 parent 의 체인을 따라가면 프로젝트의 시작으로 돌아간다.
그러나 commit 는 단순한 리스트 형식이 아니다. git 는 개발의 선이 갈라졌다가 다시 합쳐지는 것(merge)을 허용한다.
따라서 병합을 나타내는 커밋은 parent 가 하나 이상을 가질수 있다. 각각의 parent 는 각 개발 라인 의 하나에 대한 최근의 commit 이다.

commit X가 commit Y의 조상이라면 commit X 가 commit Y 로 부터 도달 가능하다고 말한다.
같은 의미로 commit Y 는 X의 자손이다 또는 commit Y 부터 commit X 까지 parent 가 chain 되어 있다.

Understanding history: History diagrams

때때로 우리는 다음과 같은 다이어그램을 사용하여 Git 히스토리를 나타낼 것입니다.
이하. 커밋은 "o"로 표시되고 커밋 사이의 링크는
-/ 및 \로 그려진 선. 시간은 왼쪽에서 오른쪽으로 이동합니다.

................................................
         o--o--o <-지점 A
        /
 o--o--o <-마스터
        \
         o--o--o <-지점 B
................................................

Understanding history: What is a branch?

우리가 명확히 할 필요가 있는게, branch는 개발 라인을 의미하며, branch head 는 branch 에서 가장 최근에 commit 을 의히한다.
위의 예에서 "A"라고 불리는 branch head 는 하나의 특정 커밋에 대한 포인터 이지만, 우리는 그 지점가지 이어지는 세 커밋의 라인을 "branch A" 의 일부로 참조한다.

Manipulating branches

`git branch` ::    모든 지점을 나열하십시오.
`git branch <branch>`::    `<branch>`라는 새 분기를 만듭니다. 현재 지점으로 역사에서 포인트.
`git branch <branch> <start-point>`:: `<start-point>`을 참조하여`<branch>`라는 새 분기를 만듭니다.
                                       분기 이름 또는 태그 이름 사용을 포함합니다.
`git branch -d <branch>`:: `<branch>`브랜치를 삭제하십시오. 지점이 완전하지 않은 경우
                            업스트림 분기에 병합되거나 현재 분기에 포함 된 경우(경고와 함께 실패)
`git branch -D <branch>`::    병합 상태에 관계없이`<branch>`브랜치를 삭제하십시오.
`git switch <branch>`::    현재 브랜치를`<branch>`로 만들어 작업을 업데이트합니다.
                         `<branch>`에서 참조하는 버전을 반영하는 디렉토리입니다.
`git switch -c <new> <start-point>`::`<start-point>`를 참조하는 새 분기`<new>`를 만들고    이동. 

특수기호 "HEAD" 는 항상 현재 branch 를 나타내는 데 사용할 수 있습니다. 사실, .git 디렉토리 밑에 HEAD 란 파일을 사용하고 있습니다.현자의 branch 를 기억하기 위해서

$ cat .git/HEAD
ref: refs/heads/master

Examining an old version without creating a new branch

"git switch" 명령은 일반적으로 branch head 를 기대하지만, --detach 로 호출할때, 임의 commit 도 수락한다.

$ git switch --detach v2.6.17
Note: checking out 'v2.6.17'.

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 performing another switch.

이러면 HEAD 는 브랜치 대신 commit 의 SHA-1 를 참조한다.
그리고 git branch 는 더이상 branch 에 있지 않음을 보여준다.

$ cat .git/HEAD
427abfa28afedffadfca9dd8b067eb6d36bac53f
$ git branch
* (detached from v2.6.17)
  master

Examining branches from a remote repository

복제할 때 생성된 master branch 는 복제한 리포지토리의 HEAD 복사본입니다. 그러나 해당 리포지토리에는 다른 branch가 있을수 있으며 로컬 리포지토리에는 원격 추적 분기라고하는 각 원격 branch가 추적되는 분기가 보관됩니다.

$ git branch -r
  origin/HEAD
  origin/html
  origin/maint
  origin/man
  origin/master
  origin/next
  origin/pu
  origin/todo

origin 은 리모트 리파지토리 또는 remote 라고 부른다.
복사 시점에 원격 branch 를 기반으로 생성되며, git-fetch (git-pull) 또는 git push 로 업데이트 된다.

이 원격 추적 branch 로 브런치를 생성할 수 있다.

$ git switch -c my-todo-copy origin/todo

Naming branches, tags, and other references

branch, remote-tracking branch ,tag 는 모두 commit 의 참조다.
모든 참조는 슬래시로 구분된 결로이름으로 명명된다. 'refs'로 시작하는

    - The branch `test` is short for `refs/heads/test`.
    - The tag `v2.6.18` is short for `refs/tags/v2.6.18`.
    - `origin/master` is short for `refs/remotes/origin/master`.

새로 생성된 참조는 실제로 .git/refs 디렉토리에 저장된다.

다른 유용한 단축키로는, 리포지토리의 HEAD 는 해당 리포지토리의 이름만 사용하여 참조할 수 있다.
origin 은 일반적으로 리포지토리 origin 의 HADE 분기에 대한 바로가기 이다.

Updating a repository with git fetch

리포지토리를 복제하고 변경사항을 commit 한 후에 원래 리포지토리의 변경을 업데이트하고 싶을때 git-fetch 명령을 사용한다.
remote-tracking branch 의 가자 최근 버전을 확인후 업데이트 한다.

Fetching branches from other repositories

다른 저장소에서 분기를 추적할 수도 있다.

$ git remote add staging git://git.kernel.org/.../gregkh/staging.git
$ git fetch staging
...
From git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
 * [new branch]      master     -> staging/master
 * [new branch]      staging-linus -> staging/staging-linus
 * [new branch]      staging-next -> staging/staging-next

새로운 remote-tranking branch는 약칭으로 저장된다.

$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  staging/master
  staging/staging-linus
  staging/staging-next

브런치를 확인해보면 remote-tracking branch 가 추가된것을 확인할 수 있다.

git-fetch 로 하면 업데이터 된다.

.git/config 파일을 보면 추가된것을 볼 수 있다.

$ cat .git/config
...
[remote "staging"]
    url = git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
    fetch = +refs/heads/*:refs/remotes/staging/*
...