# Useful:Tools/Git

  • 따로 관리하던 프로젝트를 병합해야 하는 상황이 발생했다.

  • git merge --allow-unrelated-histories 옵션을 통해 비교적 간단히 이 작업을 수행할 수 있다.

  • 합쳐진 단일 프로젝트에서 기존의 다수 프로젝트의 commit history를 모두 유지할 수 있다.


예시) 아래의 경우는 필자가 실제로 직면한 상황이다.

Original-Project/
         	.git/
         	.gitignore
         	README.md
         	App.java
         
Original-Server/
		.git/
		.gitignore
		README.md
		ServerApp.java
		
Original-Client/
		.git/
		.gitignore
		README.md
		ClientApp.java
  • 대략적으로 위와 같은 상황이 발생했으며, 하나의 저장소에 세 개의 프로젝트를 모두 병합해야 한다.

  • 위의 상황에서 각 프로젝트는 git 프로젝트이며, 간략화 했지만 다수의 파일이 존재한다.

  • 명령을 이해하며 따라가면 손쉽게 아래와 같은 구조를 만들 수 있다.


결과)

Original-Project/
         .git/
         .gitignore
         Original-Project/
         		README.md
         		App.java
         			
         Original-server/
         		README.md
         		ServerApp.java
         			
         Original-Client/
         		README.md
         		ClientApp.java       
  • 기존의 프로젝트와 서버, 클라이언트로 세 개의 저장소가 존재했고, 각 저장소는 git으로 관리되고 있었다.

  • 이를 하나의 저장소에 합치며 단일 git 프로젝트로 만든 것이다.


과정)

# 먼저 각 프로젝트 폴더를 아래와 같이 구성한다.
# git과 관련된 파일 및 폴더를 제외하고 나머지 파일을 모두 현재의 프로젝트 폴더 이름과 동일한 폴더에 위치시킨다.
Original-Project/
         .git/
         .gitignore
         Original-Project/
         		README.md
         		App.java
         
Original-Server/
	.git/
	.gitignore
	Original-Server/
			README.md
			ServerApp.java
		
Original-Client/
	.git/
	.gitignore
	Origianl-Client/
			README.md
			ClientApp.java

이후 아래의 과정을 수행한다.

# Original-Project의 경로는 /home/user/git/Original-Project 로 가정한다.
# 또한 Original-Server와 Original-Client의 위치는 Original-Project의 위치와 동일하다고 가정한다.
# Original-Project/ 위치에서 아래의 명령을 수행한다.

$ git remote add server ../Original-Server
$ git fetch server
$ git merge --allow-unrelated-histories server/master
$ git remote remove server
$ git add .
$ git commit -m "Merge server project into original-project"

$ git remote add client ../Original-Client
$ git fetch client
$ git merge --allow-unrelated-histories client/master
$ git remote remove client
$ git add .
$ git commit -m "Merge client project into original-project"
  • 원격 저장소를 연결할 때 별칭이나 폴더명은 본인에 맞게 적절히 적용한다.

  • 병합시에 .gitignore 파일이 충돌할 수 있다.

    • 충돌은 파일을 열어 적절히 수정하고 commit하여 해결한다.

  • commit history가 유지되는 것을 확인하고, 추가적으로 필요하다면 github에 새로운 remote repository를 만들어 push할 수 있다.

  • --allow-unrelated-histories 옵션은 세 개의 프로젝트의 commit history의 조상이 같지 않기 때문에 사용한다.

    • 커밋 조상이 같지 않은 프로젝트를 병합하는 것을 허용하겠다는 의미이다.


 

설정

사용자 이름과 이메일 설정

  • git config --global user.name "UserName"
  • git config --global user.email "UserEmail"

 

 

텍스트 편집기 설정

  • git config --global core.editor vim

 

Line Ending 설정

  • git config --global core.autocrlf [ true | input | false ]
    • windows에서는 true로 설정하고 linux, mac, unix에서는 input을 사용한다.

Local Repository를 위한 Git Command

  • git init
    • git 저장소 초기화

 

  • git add [ filename | . | * ]
    • untracked 파일을 tracked로 만들거나 unstaged 파일을 staged로 만들 때 사용
    • 즉, 추적하지 않은 파일을 추적하거나 수정된 파일을 commit 하기 위해 staging area에 등록하는 데 사용하는 명령어

 

  • git commit
    • staged 상태의 내역을 최종적으로 저장소에 반영하는 명령
    • -a 옵션은 add를 동시에 수행하며, -m 옵션은 간단한 commit 메시지 작성을 위해 사용한다.

 

  • git commit --amend
    • git status가 clean한 상태에서 최신 커밋(마지막 커밋) 내용을 수정한다.
      • 부가적으로 설명하면, 마지막 커밋의 내용을 수정하는 것이 아니라, 마지막 커밋을 대체하는 새로운 커밋을 만드는 것이다.
      • 해당 커밋의 체크섬 값이 변화하는 것을 확인할 수 있다.
    • 이미 remote repository에 push한 경우 주의해서 사용한다.

 

  • git status
    • 현재 저장소의 상태 확인을 위한 명령
    • 추적되지 않은 파일이 있거나 변경되었는데 commit되지 않은 내역 등을 알려준다.

 

  • git branch
    • 해당 명령 자체로는 어떠한 branch가 존재하는지 확인할 수 있다.
    • -a 옵션 또는 -r 옵션을 이용하여 원격 저장소의 연결된 브랜치를 확인할 수 있다.

 

  • git branch [ BranchName ]
    • 해당 브랜치를 생성한다.

 

  • git checkout [ BranchName ]
    • 해당 브랜치로 체크아웃한다.
    • -b 옵션을 통해 브랜치를 생성하면서 동시에 체크아웃할 수 있다.

 

  • git merge [ BranchName ]
    • 현재 작업중인 branch에 명시한 branch를 병합한다.

 

  • git log
    • -5와 같이 옵션을 사용해 해당 개수만큼 로그를 확인할 수 있다.

 


Remote Repository를 위한 Git Command

  • git clone https://github.com/user-name/repository-name.git  
    • 위의 형태로 원격 저장소의 내용을 로컬 저장소로 가져올 수 있다.
    • clone 한 저장소의 별칭은 따로 명시하지 않으면 origin으로 지어진다.

 

  • git remote add origin https://github.com/user-name/repository-name.git 
    • 원격 저장소와 로컬 저장소를 연결한다.
    • 위의 경우는 origin이라는 별칭으로 현재 로컬 저장소와 링크로 명시한 원격 저장소를 연결한다.

 

  • git remote -v
    • 원격 저장소와의 연결을 확인할 수 있다.

 

  • git push
    • 기본적으로 commit을 원격 저장소의 master branch에 업로드한다.
    • 또한, 다양한 옵션을 통해 특정 branch를 가져오거나 업로드할 수 있으며 tag를 업로드할 수 있다.

 

  • git push origin [ --all | BranchName ]
    • 현재 로컬 저장소의 모든 branch를 별칭에 해당하는 원격 저장소에 업로드한다.
    • 만약 원격 저장소에 로컬 저장소에서 업로드하는 이름의 branch가 없다면 새로 생성한다.

 

  • git pull & git fetch
    • 원격 저장소의 정보를 가져와 로컬 branch에 merge까지 수행한다.
      • 즉, fetch + merge의 형태이다.
    • pull을 사용하면 병합되면서 변경된 프로젝트의 세세한 부분을 파악할 수 없다.
      • 따라서 팀 프로젝트에서 권고되지 않으며, fetch를 이용해 원격 저장소의 커밋을 가져오고 로컬 저장소에서는 이를 수동으로 merge 하는 방법이 권고된다.

기타 명령어

  • git tag [태그 내용] [commit checksum]
    • 특정 커밋을 참조하는 태그를 붙인다.
    • 간단하게 이름만 붙이는 light weight tag와 보다 많은 정보 전달을 위한 annotated tag가 있다.
    • 보통 배포 버전을 명시하는데 활용된다.

 

  • git tag -l
    • 현재 저장소에 존재하는 태그의 리스트를 출력한다.

 

  • git show-ref --tags
    • 태그와 함께 태그가 붙은 commit의 체크섬 값을 같이 출력한다.

 

  • git tag -a [태그 내용] [commit checksum]
    • annotated 태그를 붙인다.
    • 해당 명령을 수행하면 에디터가 실행된다.
      • 보통 언제, 누가, 왜 이 태그를 붙였는지 입력한다.

 

  • git show [tag]
    • 태그를 확인한다.

 

  • git push [remote repository] [branch] --tags
    • 로컬의 특정 branch의 모든 태그를 명시한 별칭의 원격 저장소에 push
    • oriigin master가 기본값

 

  • 프로젝트가 커지면서 하위 디렉토리를 별도의 프로젝트로 분리해야하는 상황이 발생했다.
  • subtree 명령을 이용하여 쉽게 작업을 진행할 수 있다.
  • 분할된 각각의 프로젝트가 commit 내역을 유지하므로 Github에서 잔디를 유지할 수 있다.

예시) 아래의 경우는 필자가 실제로 직면한 상황이다.

Original_Project/		
         SubDirectory01/
         SubDirectory02/
         docs/
         .git/
  • 대략적으로 위와 같은 상황이 발생했으며, SubDirectory02가 너무 커져서 다른 프로젝트로 분리해야하는 상황이다.
  • 명령을 이해하며 따라가면 손쉽게 아래와 같은 구조를 만들 수 있다.

결과

new_project_name01/
		# 기존 폴더 내용 유지
        docs/         
        .git/

new_project_name02/
		# 기존 폴더 내용 유지
        docs/         
        .git/
  • 즉 SubDirectory01과 SubDirectory02가 하나의 프로젝트였지만, 각각의 프로젝트 디렉토리로 분리하고 필요한 파일들을 해당 프로젝트에 맞게 옮겨주는 작업이다.
  • 필요에 따라 Original_Project에 SubDirectory01을 남기고 SubDirectory02만 다른 프로젝트로 분리할 수 있다.

과정

# Original_Project/ 위치에서 아래의 명령을 수행한다.
# Original_Project의 경로는 /home/user/git/Original_Project 로 가정한다.

$ git subtree split -P SubDirectory02 -b copybranch
$ mkdir ../new_project_name02
$ cd ../new_project_name02
$ git init
$ git pull /home/user/git/Original_Project/ copybranch
$ git remote add origin https://github.com/user_id/new_project_name02
$ git remote -v
$ git push origin -u master
  • user_id와 new_project_name은 본인에 맞게 입력한다.
  • 위의 작업 이후 commit 내역은 유지되면서 SubDirectory02가 다른 프로젝트 폴더로 분리됐음을 확인할 수 있다.
  • 또한 가장 중요한 잔디가 살아있음을 확인할 수 있다.

SubDirectory01을 Original_Directory에 유지하고 싶다면 아래와 같은 작업을 수행한다.

# Original_Project/ 위치에서 아래의 명령을 수행한다.
# Original_Project의 경로는 /home/user/git/Original_Project 로 가정한다.

$ git rm -r SubDirectory02
$ git commit -m "split SubDirectory02 and remove SubDirectory02 in Original_Directory"
$ git branch -D copybranch
  • SubDirectory01 또한 다른 프로젝트 디렉토리로 구성해야 하는 상황이라면 위의 작업 대신 SubDirectory02에 진행한 작업을 수행한 후 기존의 Original_Directory를 로컬과 원격 저장소에서 제거한다.
  • 단, 삭제하기 전에 docs/ 와 같은 추가적으로 옮겨줘야 할 파일이 있다면 신경쓰도록 한다.

Git 저장소 만들기(git init, git clone)

두 가지 방법으로 Git 저장소를 생성할 수 있다.

하나는 기존에 사용하던 프로젝트 디렉토리를 Git 저장소로 만드는 것이고, 다른 하나는 서버에 있는 저장소를 로컬로 복제하는 것이다.


기존에 사용하던 디렉토리를 Git 저장소로 만들기

$ mkdir git_study
$ cd git_study
$ git init
  • 위 명령을 실행하면 git_study 디렉토리에 .git이라는 하위 디렉토리가 생성된다.
  • .git 디렉토리에는 프로젝트 저장소에 필요한 파일들이 들어 있다.
  • Git은 현재 어떤 파일도 관리하지 않으며, 파일을 관리하게 하려면 저장소에 파일을 추가하거나 수정하고 commit해야 한다.

 

$ git add Hello.java
$ git add .gitignore
$ git commit -m "create project directory"
  • git add 명령은 Stage Area(index)에 파일을 추가하고 git commit 명령은 Stage Area의 스냅샷을 찍어 로컬 저장소에 저장한다.
  • 자세한 내용은 추후에 다룬다.

기존 저장소를 복제하기

  • 오픈소스(다른 프로젝트)에 참여해서 기여하거나 다른 저장소를 복제하고 싶을 때 git clone 명령을 이용한다.
  • 기존의 VCS와의 차이점은 원격 저장소(서버)에 있는 거의 모든 데이터를 복사한다는 점이다.
    • 서버의 저장소가 망가져도 클라이언트의 저장소를 이용해 복구할 수 있다.
$ git clone https://github.com/yh0921k/TIL.git
$ git clone https://github.com/yh0921k/TIL.git myTIL # 다른 디렉토리 이름으로 clone

위의 명령은 TIL이라는 디렉토리를 만들고 그 안에 .git 디렉토리를 만들며 저장소를 초기화한다.

또한 서버의 히스토리를 모두 가져와서 적용하므로 당장 작업을 시작할 수 있다.


[출처]

https://git-scm.com/book/en/v2

[라이센스]

https://creativecommons.org/licenses/by-nc-sa/3.0/

Git의 세 가지 상태

2019. 12. 18. 14:46

Git은 파일을 Committed, Modified, Staged의 세 가지 상태로 관리한다.

  • Committed란 데이터가 로컬 데이터베이스에 안전하게 저장됐음을 의미한다.
  • Modified는 수정한 파일을 아직 로컬 데이터베이스에 commit하지 않은 상태를 말한다.
  • Staged란 현재 수정한 파일을 곧 commit할 것이라고 표시한 상태를 의미한다.

위의 세 가지 상태는 Git 프로젝트의 세 가지 단계와 연결된다.

  • Git 디렉토리, 워킹 트리, Staging Area를 이해해야 한다.

Git 디렉토리는 Git이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다.

  • .git 디렉토리가 Git의 핵심이다.
  • 다른 컴퓨터에 있는 저장소를 복제할 때 해당 디렉토리가 만들어진다.

워킹 트리는 프로젝트의 특정 버전을 Checkout 한 것이다.

  • Git 디렉토리는 지금 작업하는 디스크에 있고 디렉토리 안에 압축된 데이터베이스에서 파일을 가져와서 워킹 트리를 만든다.

Staging Area는 Git 디렉토리에 있다.

  • 단순한 파일이며, 곧 commit할 파일에 대한 정보를 저장한다.
  • "index"라는 이름으로 불리기도 하지만 Staging Area라는 명칭이 표준이 되어가고 있다.

Git에서 하는 일은 기본적으로 아래와 같다.

  1. 워킹 트리에서 파일을 수정한다.
  2. Staging Area에서 파일을 Stage 해서 commit할 스냅샷을 만든다.
  3. Staging Area에 있는 파일들을 commit해서 Git 디렉토리에 영구적인 스냅샷으로 저장한다.

즉, Git 디렉토리에 있는 파일들은 Committed 상태이다. 파일을 수정하고 Staging Area에 추가했다면 Staged이다. 그리고 Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았다면 Modified 이다.


[출처]

https://git-scm.com/book/en/v2

[라이센스]

https://creativecommons.org/licenses/by-nc-sa/3.0/

Git 시작하기

설치 및 Version 확인

Ubuntu를 기준으로 apt-get install git 명령을 이용하면 Git을 설치할 수 있다.

또한, 버전을 확인하기 위해 git --version 명령을 이용할 수 있다.


최초 설정

Git을 설치하고 사용환경을 적절하게 설정해야 한다. git config 명령은 설정 내용을 확인하고 변경할 수 있다.

Git은 아래의 세 가지 파일의 설정 내용에 따라 동작한다.

  • /etc/gitconfig
    • 시스템의 모든 저장소와 모든 사용자에게 적용되는 설정 파일
    • git config --system 명령으로 이 파일을 읽고 쓸 수 있다.
  • /.gitconfig, ~/.config/git/config
    • 현재 사용자와 해당 사용자가 사용하는 모든 저장소에 적용되는 설정 파일
    • git config --global 명령으로 이 파일을 읽고 쓸 수 있다.
  • .git/config
    • git 디렉토리에 존재하며 현재 작업 중인 프로젝트에 적용되는 설정 파일
    • --local 옵션을 사용해 사용할 수 있다.

각 설정은 3 > 2> 1 순으로 우선순위가 높다.


사용자 이름과 이메일 설정

Git을 설치하면 가장 먼저 해야하는 설정이다. Git은 commit을 할 때마다 이 정보를 사용하며, 한 번 커밋한 후에는 정보를 변경할 수 없다.

 

    git config --global user.name "User Name"

    git config --global user.email "Email Address"

 

위에서 말했다시피 --global 옵션으로 수행하는 설정은 한 번만 하면 된다.
약 프로젝트마다 다른 이름과 이메일 주소를 사용하고 싶으면 --global 옵션을 빼고 명령을 실행한다.

 

 

에디터 설정

Git에서 사용할 텍스트 에디터를 설정한다.

 

  git config --globla core.editor vim

 


설정 확인

git config --list

Git은 설정 값을 여러 파일에서 읽기 때문에 같은 설정이 존재할 수 있다. 이 때 Git은 가장 나중 값을 사용한다.

 

git config <Key>

위의 명령으로 Git이 특정 Key에 대해 어떤 값을 사용하는지 확인할 수 있다.


[출처]

https://git-scm.com/book/en/v2

[라이센스]

https://creativecommons.org/licenses/by-nc-sa/3.0/

 

 

+ Recent posts