TIL 42. git & github

rahula·2021년 6월 17일
0
post-thumbnail

git과 github에 대해 공부한 점들을 기록합니다. 이 글은 git 공식문서와 wecode의 자료를 토대로 썼습니다.

git의 local repository

git이란?

Git의 공식 명칭은 분산 버전 관리 시스템 (VCS) 입니다. 쉽게 말해, 프로젝트 파일의 변경 사항을 추적하는 시스템입니다. 이를 통해 개발자들은 프로젝트의 변경 사항을 기록하고, 특정 시점의 버전으로 언제든 돌아갈 수 있습니다.

git은 버전을 관리하기 위해 파일들을 녹화한다는 느낌이라고 이해할 수 있다. 다른거 필요 없이, 1. 다른 사람들과 코드를 공유하고 생각을 주고받을 수 있다.
2. 한 프로젝트를 여러가지 버전으로 관리할 수 있다.

평행우주가 생각난다. 선택을 후회하는 일은 빈번하다. 그래서 항상 우리는 '아, 그 선택을 하지 않았더라면..'이라는 생각을 한다. git과 브랜치는 평행우주의 어디로든 갈 수 있게 해주는 타임머신과 같다.

repository

Git으로 관리하는 프로젝트 저장소.

Git repository 에는 크게 두 가지 종류가 있습니다.

  1. Local repository - 본인의 컴퓨터에 저장된 로컬 버전의 프로젝트 저장소
  2. Remote repository - 로컬 repository 와는 반대로 내 컴퓨터가 아닌 외부 (일반적으로 원격 서버) 버전의 프로젝트 저장소. 팀에서 작업 할 때 특히 유용합니다.

If you have a project directory that is currently not under version control and you want to start controlling it with Git, you first need to go to that project’s directory.

init : git local repository 생성

git init

This creates a new subdirectory named .git that contains all of your necessary repository files — a Git repository skeleton. At this point, nothing in your project is tracked yet.

프로젝트 해당 directory 안에서 git init이라고 치는 순간, 해당 폴더 내에 숨겨진 .git 디렉토리를 생성한다. .git 디렉토리 안에는 git이 추적하는 모든 정보가 들어간다. 이제 git은 현재 저장소에 대한 모든 변경사항을 추적하기 시작한다. 한 마디로, local repository는 이미 생성한 셈이다. 그러나 아직은 아무 파일도 tracking되고 있지 않다.

주의 : git의 추적과 추적기록을 전부 없애려면 rm -rf .git 명령어를 치면 된다. 말 그대로 .git폴더를 삭제하는 것.. 절대 해서는 안된다.

clone : 코드와 버전 가져오기

Git receives a full copy of nearly all data that the server has. Every version of every file for the history of the project is pulled down by default when you run git clone.

remote repository의 모든 파일, 코드들을 local repository로 다운로드받는다고 생각하면 된다. 그런데 신기한 점은, git의 모든 log들이 다 나온다는 것.

즉, git clone은 해당 remote repository의 모든 버전들까지 가져온다. 만약 내가 local repository로 만들던 파일들이 없어진다고 가정해보자. 그때 파일들만 없어지는게 아니라 git이 추적하던 모든 변경사항, 버전들까지 사라진다면 정말 큰 문제가 된다.

그래서 remote repository에서 해당 정보를 담고 있고, git clone을 할 때에도 편의를 위해 버전까지 모두 가져오는 듯하다.

status : git 상태 확인하기

git status

it으로 작업 할 때 굉장히 자주 사용되는 명령어입니다. 어떤 파일이 변경되었는지, 어떤 파일이 추가되었는지 등을 전부 보여줍니다.

이름으로 예상할 수 있듯이 상태를 보는 명령어이다. 현재 git이 추적하는 파일들이 staging area에 있는지 없는지를 보여준다. commit을 남기려면 staging area로 추가해야 한다.

이 경우는 두 파일에 변경사항이 있지만, 아직 staging되지 않았다는 사실을 알려준다. 맨 밑에서는 이 변화들이 add

이 경우는 한 파일에 변경사항이 있지만, track되고 있지 않는다는 사실을 알려준다. 그리고 git add명령어를 써서 commit될 수 있도록 하라고 설명도 해준다.

스테이징이란 뭔가? staging이 git의 평소 추적과 다른 점은 뭔가?

add : track 시작(Staging area에 파일 추가하기)

git add .

위의 명령어는 해당 디렉토리 내의 모든 파일과 디렉토리들을 git의 staging area에 추가시킨다. staging area에 들어가고 나면, commit이 되거나 아직 commit이 되지 않거나 둘 중 하나이다.

.은 해당 디렉토리의 모든 변경사항을 staging area에 추가하겠다는 의미이다. 다른 경로 커맨드와 마찬가지로 특정파일.확장자의 형식이나 *.확장자로 특정 파일 혹은 특정 종류의 파일들만 staging시킬 수 있다.

Remember that each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot; they can be unmodified, modified, or staged. In short, tracked files are files that Git knows about.

local repository에서 git의 lifecycle

As you edit files, Git sees them as modified, because you’ve changed them since your last commit. As you work, you selectively stage these modified files and then commit all those staged changes, and the cycle repeats.

git의 lifecycle. git add를 하기 전에는 변경 사항이 working tree에서만 유효하다. git add이후엔 해당 변경사항들이 stage에 올라가 있다. 그리고 git commit을 하게 되면 git은 local repository에 기록하게 되고(하나의 버전이 되는 것), 해당 변경사항은 staging area에서 내려온다. 그리고 또 git add를 하기 전에는 git이 변경되었다는 사실만 추적을 하고 있다. local repository에서 git의 사용은 이 과정의 반복이다.

The git add command takes a path name for either a file or a directory; if it’s a directory, the command adds all the files in that directory recursively.

git add의 대상이 directory일 경우, 해당 directory안의 모든 파일 변경사항들을 staging하게 된다.

이미 git add를 통해 staging된 파일이지만, 또 내용이 변경되었다면 해당 변경사항은 아직 staging된 게 아니다. 그래서 그 변경사항을 staging 적용시키려면 다시 git add를 해줘야 한다.

It turns out that Git stages a file exactly as it is when you run the git add command. If you commit now, the version of CONTRIBUTING.md as it was when you last ran the git add command is how it will go into the commit, not the version of the file as it looks in your working directory when you run git commit. If you modify a file after you run git add, you have to run git add again to stage the latest version of the file.

git status -s

git status -s로 git status를 짧게 볼 수 있다.

New files that aren’t tracked have a ?? next to them, new files that have been added to the staging area have an A, modified files have an M and so on. There are two columns to the output — the left-hand column indicates the status of the staging area and the right-hand column indicates the status of the working tree.

??는 working tree에는 존재하지만 git stage에 들어가지 않은, 그래서 아직 git이 변경사항을 추적하고 있지 않은 파일이다.
M은 modified의 약자로, git stage에 있던 파일에 변경사항이 있었음을 뜻한다.
A는 added의 약자로, working tree에 존재하던 파일(혹은 새로 생성된 파일)이 새롭게 git stage에 들어갔다는 뜻.
D는 git이 추적하던 파일이 working tree에서 삭제되었다는 뜻.

설명하는 열이 두 줄인데, 왼쪽은 git의 staging area에서 일어나는 일들을 설명하는 줄이고 오른쪽은 working tree에서 일어나는 일들을 설명하는 줄이다.

README.md파일은 이전에 변경사항들이 staging area에 들어갔지만 (commit되지 않음), working tree에서 새로운 변경사항이 생겼다.
README2.md파일은 working tree에서는 변경사항이 생겼지만, 해당 변경사항들이 staged되지 않았다.
README3.md파일은 파일 자체가 새로 staging area에 들어갔다.
a.md파일은 원래는 staging area에 있었지만, working tree에서 삭제되었다는 걸 뜻한다. 그러나 아직 삭제되었다는 사항이 staging area에 들어오지 않았다.

diff : 변경사항 구체적으로 보기

you’ll probably use it most often to answer these two questions: What have you changed but not yet staged? And what have you staged that you are about to commit?

git diff는 아직 staging area에 들어가지 않은, 즉 working tree에서 일어난 변경사항들만을 표시한다.

git diff --staged는 staging area에 들어간 변경사항들만을 표시한다.

그리고 commit을 하는 순간, git diff는 어떤 변경사항도 보여주지 않는다. 이미 버전화가 되었기 때문에, 더 이상 변경사항이 아니게 되기 때문이다.

restore : 변경사항 되돌리기

많이 쓸 일은 없겠지만, git restore을 사용하면 local repository에서 일어난 변경사항이 아직 commit이 된 상태가 아니라면, 이전 버전으로 되돌릴 수 있다.

만약 staging area에 올려놓은 상태라면 앞에 --staged를 붙이면 staging area에서 해당 파일의 변경사항을 내릴 수 있다. 또한 아직 staging area에 있지 않은, working tree에서의 변경사항만 있는 상태라면 git restore을 이용해서 working tree에서의 변경사항을 이전으로 되돌릴 수 있다.

.gitignore : git상에서 숨기기(무시)

.gitignore은 하나의 파일이고, 설정파일에 가깝다. 설정 파일이나 부가적인 파일들처럼 local repository에서 매번 다루기 귀찮거나, 비밀번호처럼 민감한 정보를 담고 있는 파일의 경우 특정 파일 혹은 확장자를 숨길 수 있다.

commit

Remember that anything that is still unstaged — any files you have created or modified that you haven’t run git add on since you edited them — won’t go into this commit.

commit은 staging area에 올라간 변경사항들에 대해서만 이루어진다. 즉, git add로 staging area에 올려놓지 않은, working tree에서만 이뤄진 변경사항은 절대 commit에 포함되지 않는다.

git commit -m "Commit message"

커밋 후 :

Remember that the commit records the snapshot you set up in your staging area. Anything you didn’t stage is still sitting there modified. Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later.

-a : staging을 건너뛸 수 있다. 확신이 드는 변경사항이라면 이렇게 commit하는게 편할 듯.

이제는 track되지 않는 파일만 남아있다.

--amend : commit 메세지를 바꿀 수 있다.

모든 commit history를 보려면 git log. log는 각 커밋에 대한 자세한 정보를 담고 있습니다. (작성자, hash 값, 날짜와 시간, 그리고 커밋 메세지)

특정 commit 시점으로 돌아가고 싶다면 git checkout 해쉬

github : git의 remote repository

To be able to collaborate on any Git project, you need to know how to manage your remote repositories. Remote repositories are versions of your project that are hosted on the Internet or network somewhere.

github란?

git이 분산버전관리시스템이라면, github는 그런 git이 추적하는 버전들이 모이는 곳이라고 보면 된다.

GitHub을 사용하여 로컬 프로젝트 repository를 원격 클라우드 기반 GitHub 저장소에 업로드 할 수 있고, public repository 들을 통해 다른 개발자들과 교류할 수도 있습니다.

추가적으로 다른 사람들이 내 코드를 보고 내가 어떤 개발자인지 알 수 있게 할 수도 있고, 다른 개발자들과 연결하는 미디어로써도 기능이 좋기 때문에 깃허브는 필수다.

github 단계

Common Workflow: 내 로컬 Repository를 GitHub 에 push 하기

  1. local repository에서 add 및 commit을 한다.
  2. github에서 새 remote repository를 생성한다.
  3. 나의 local repository를 remote repository와 연결
    git remote add origin 레퍼지토리주소
    여기서 origin은 변수명으로 쓰인다. 따라서 다른 remote주소를 만들 수도 있고, 그냥 이름만 다르게 지을 수도 있다.
  4. 새 remote를 이용해서 코드를 push한다.
    git push -u origin master

git remote add : remote repository 연결

git remote add <shortname> <url> : local repository와 remote repository를 연결짓는다. <shortname>부분은 어떤 이름이든 될 수 있다. 기본적으로는 origin이라는 이름으로 되어있다. 그러나 변수명처럼 바뀔 수 있고 여러 remote repository를 쓸 수 있기 때문에 여러 이름을 가질 수 있다.

push : remote repository로 버전 올리기

git push <shortname> <branchname>

git fetch : remote repository에서 data가져오기

git fetch <remote>

The command goes out to that remote project and pulls down all the data from that remote project that you don’t have yet.

git pull : fetch와 merge를 동시에

If your current branch is set up to track a remote branch, you can use the git pull command to automatically fetch and then merge that remote branch into your current branch.

branch

git이 데이터를 담는 방식

Git doesn’t store data as a series of changesets or differences, but instead as a series of snapshots. When you make a commit, Git stores a commit object that contains a pointer to the snapshot of the content you staged. This object also contains the author’s name and email address, the message that you typed, and pointers to the commit or commits that directly came before this commit

branch란?

브랜치란 독립적으로 어떤 작업을 진행하기 위한 개념입니다. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있습니다.

Branching means you diverge from the main line of development and continue to do work without messing with that main line.

commit과 tree, snapshot

blobs (each representing the contents of one of the three files), one tree that lists the contents of the directory and specifies which file names are stored as which blobs, and one commit with the pointer to that root tree and all the commit metadata.

각각의 commit은 snapshot(commit할 시점의 파일내용들, 즉 변경사항들)을 포인팅하고 있다고 이해하면 된다.

How does Git know what branch you’re currently on? It keeps a special pointer called HEAD.

HEAD는 branch중에서도 local에서 현재 자신이 있는 branch임을 뜻한다. 사진에선 지금 master branch에 있다.

create new branch

git branch 새로운브랜치

What happens when you create a new branch? Well, doing so creates a new pointer for you to move around.

switch branch

git checkout testing

branch를 생성하는 동시에 전환하고 싶다면 checkout 뒤에 -b를 붙여준다.

만약 master이 아닌 다른 branch에서, master보다 앞서는 변경사항을 만든다면 어떻게 될까?

master branch의 파일내용 :

testing branch의 파일 내용 :

이 상황의 도식화 :

만약 git checkout master을 한다면?

That command did two things. It moved the HEAD pointer back to point to the master branch, and it reverted the files in your working directory back to the snapshot that master points to. This also means the changes you make from this point forward will diverge from an older version of the project. It essentially rewinds the work you’ve done in your testing branch so you can go in a different direction. when you switch branches, Git resets your working directory to look like it did the last time you committed on that branch. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it.

HEAD는 master branch를 포인팅하게 된다. 즉, working tree의 모든 내용이 master branch의 내용으로 바뀌게 된다.

그럼 master에서 testing branch와 내용을 다르게 만든다면?

branch 병합

어떤 제품에 대한 테스트를 하고 싶다면, 원래 쓰던 branch를 모두 바꾸는 것 보다는, 기존의 유지할 부분은 유지하되 새로운 branch에서 작업하는 쪽이 안전할 것이다.

git merge <branchname>

이제 전체 branch의 모양새는 다음과 같다 :

여러 branch의 변경사항을 한 branch로 병합할 수 있다. git은 branch들의 공통되는 조상을 찾은 다음, 다른 변경사항들을 짜집기해서 병합시킨다.

주의 : 서로 같은 파일 혹은 디렉토리에 다른 변경사항이 있다면, merge시 충돌이 일어난다. 따라서 최소한 한 쪽에는 변화가 없는 (중점으로 두려는 파일에 대해서) 상태에서 병합을 진행해야 한다.

branch 삭제

테스팅용 branch에서 테스트가 끝나고 merge가 끝났다면, 해당 branch를 삭제해주면 된다.

git branch -d 브랜치

merge conflict

Occasionally, this process doesn’t go smoothly. If you changed the same part of the same file differently in the two branches you’re merging, Git won’t be able to merge them cleanly.

Git hasn’t automatically created a new merge commit. It has paused the process while you resolve the conflict.

repository 클론

git clone 레포지토리링크

: 해당 경로에 레포지토리의 모든 파일들을 받을 수 있다.

master branch를 clone후 merge하기

master 브랜치를 건드릴 필요없이 작업환경에서 기능을 추가하거나 테스트를 진행할 수 있게 되는것이죠. 나중에 전부 완료가 된다면, 그 때 master 브랜치와 merge (병합) 해줄 수 있습니다.
커스텀 브랜치를 push 하고 master 브랜치에 적용될 준비가 되었다면, Pull Request (PR) 라는 것을 통해 프로젝트 오너 (혹은 팀 리더) 에게 내가 작업한 브랜치의 작업내용을 master 브랜치에 반영해달라는 요청을 보낼 수 있습니다.
새로운 아이디어가 떠올라서 기존의 코드를 바꾸려는데, master을 건드리자니 위험하다 싶을 때가 있을거다. 그럴 때 새로운 branch를 만드는 거다. 기존의 master branch 코드를 가져오되, 다른 branch에서 작업을 하면 위험한 일이 생길 걱정이 없다.

pull request 생성

커스텀 브랜치를 push 하고 master 브랜치에 적용될 준비가 되었다면, Pull Request (PR) 라는 것을 통해 프로젝트 오너 (혹은 팀 리더) 에게 내가 작업한 브랜치의 작업내용을 master 브랜치에 반영해달라는 요청을 보낼 수 있습니다.

커스텀 브랜치를 push 하고 master 브랜치에 적용될 준비가 되었다면, Pull Request (PR) 라는 것을 통해 프로젝트 오너 (혹은 팀 리더) 에게 내가 작업한 브랜치의 작업내용을 master 브랜치에 반영해달라는 요청을 보낼 수 있습니다.

질문

  1. git의 local repository에 코드를 저장하려면 일단 commit을 하면 되나? remote repository랑 별개로 관리할 수가 있는건가. 그러면 commit을 한 시점으로 돌아가면 되는거니까. git checkout은 branch에서도 쓰이던데, branch와 hash(git의 시점)이 결국 같은개념인건가?
  2. branch를 삭제하고 remote repository에 어떻게 반영할까?
  3. pull request는 감이 안온다. 그냥 merge에 대한 권한으로 이해중.
  4. git tagging이란? 중요한 버전을 tag로 만들어서 언제든 돌아갈 수 있으면 편할 것 같다.
  5. 같은 파일에 서로 다른 변경사항이 있더라도 merge 충돌이 안 일어날 수도 있나?
profile
백엔드 지망 대학생

0개의 댓글