-
Git2 - CLI (1)Version Control생활코딩 Git 2021. 10. 5. 22:25
--------------------------------------------------------------------------------------------------------------------
@Git2 Cli 버전관리 - 1.수업소개
원래 오리지널 Git이라고 하면 Cli의 방법을 얘기하는것임 --깃을 쓸 수 있는 여러가지 프로그램인 토토이스깃, 소스트리, 깃허브 데스크탑 얘네도 내부적으로는 이걸 사용
개발자들이 이 방법을 선호해
1.익숙해지면 복잡한 GUI없이 간편하게 다룰 수 있다.
2.명령어의 특성상 처리해야할일을 한번에 명령해서 자동화를 할 수가 있다.
3.GUI로 제어할 수 없는 서버환경에서도 쓸 수 있는 유일한 방법.
깃은 파일의 이름을 더럽히지 않으면서도 모든 변경사항을 보존할 수 있고
그 변경사항에 대한 풍부한 해설을 추가할 수 있다니 멋지지 않나요? 기대되시죠? 기대하세요 안하면 자기손해 거든요
--------------------------------------------------------------------------------------------------------------------
@설치 맥
깃 하면 얘기하는 프로그램, 명령어를 사용해서 제어하는 프로그램 을 설치할거야
스팟라이트에서 > terminal > git 쳐보고 뭐가 많이 뜨면 git이 이미 깔려 있는 것
안깔려 있을 때 xcode를 설치할거냐 이러는데 yes를 하면 어떤 프로그램이 자동으로 깔림
그래도 안되면 홈페이지로 가서 git-scm.com
이 깃의 홈페이지 ---를 대시라고 하시네
다운로드 받은 파일을 더블클릭했을 때 뭐가 뜨면 우클릭으로 open
그다음 open --다운받은게 바이러스가 있을 수 있기 때문에 실행할 때 까다롭게 함
깔면 터미널을 껐다가 다시 키고
git을 쳐보면git에 대한 설명이 쭉 뜬다
--------------------------------------------------------------------------------------------------------------------
@설치 Windows
우리가 설치할건 정식명칭은 아니지만 original git
git이라고 하면 그 원조격인 가장 중요한 프로그램
명령어를 이용해서 git을 제어하는 프로그램
git-scm.com
설치, 다 그냥 next
검색에 git 해보면 Git Bash라는 게 깔려있고 실행하면 시커먼 창이 뜨는데 콘솔 또는 터미널이라고 한다.
git을 쳐보면 설명이 뜬다? 성공
--------------------------------------------------------------------------------------------------------------------
@3.버전관리의 시작
깃에게 어떤 특정한 디렉토리를 버전관리를 하고싶으니까 거기를 관리해 라고 할 것.
pwd하니까 /가 나와서 cd ~ 함
: ~는 기본위치이지 시작위치가 아닌가봐
어떤 폴더 안에서
나 이제 이 디렉토리 안에서 작업할 거니까 이 디렉토리를 버전관리 하기 시작해!
git init .initialize(초기화)의 약자현재 디렉토리인 .
이러면 이제 .git이라는 디렉토리가 생김 여기로 들어가서 ls -al 해보면 여러 파일과 디렉토리가 있음.
바로 이게 .git디렉토리의 부모디렉토리, 프로젝트의 파일들을 보관하려고 하는 디렉토리
에 생성되는 여러가지 변화들을 버전으로 만들건데 그 버전정보들이 .git이라는 디렉토리 안에 각자 취지, 역할에 따라서 적당히 저장됨. .git이라는 디렉토리를 지우면 안돼 우리 프로젝트의 역사가 사라짐
--------------------------------------------------------------------------------------------------------------------
@4.버전 만들기
우리가 하려는 건 파일을 변경했을 때 그 변경사항들을 버전으로 만들어서 관리하는 것
Working tree : 우리가 파일을 만들고 수정하고 할 텐데 아직 버전으로 만들어지기 전 단계, 수정하는 곳, 수정한 파일들.
Staging Area : 버전을 만들려고 하는 파일들. 우리가 버전을 만들려고 할 때 파일이 열개면, 우리가 다 그걸 버전으로 만들게 아니라 파일 두개만 콕 집어서 하나의 버전으로 만들고 싶으면 Staging Area라는 곳에 그 두개의 파일을 올려야 함10개를 수정했는데 두개의 파일만 올리는 것. 그 다음 git에게 버전을 만들라고 하면 Staging Area에 있는 두개의 파일만 모아서 하나의 버전으로 만들어서 Repository에 넣음.
Repository(저장소) == .git : 만들어진 버전. 깃에서 버전이 저장되는곳
이 부분이 젤 어렵대
hello1.txt 파일을 만듦, 내용은 1
cat은 뒤에 따라오는 파일이름의 내용을 출력
git을 사용하면서 가장 많이 사용할 명령어는 git status : 니 상태 어때
No commits yet : 아직 버전이 없어서 *commit = version
Untracked : 추적되지 않고 있는, 파일이 hello1.txt다
깃에선 명시적으로 나 이 파일을 버전관리할거야 라고 '한번' 알려줘야 함. 안그러면 깃은 걔를 없는 셈 침
깃에게 아직 얘 관리해 라고 하지 않았기 때문에 Untracked상태.(나중에 알게 됩니다)
그럼 이제 hello1.txt를 버전으로 만들기 위해선 아까 말했던 것처럼 Staging Area에 올려야함
그때 사용하는 명령이 add
git add hello1.txt
hello1.txt라는 파일, working tree의 수정사항, 을 버전으로 만들거니까 Staging Area에 올려! 라는 뜻
Untracked였던 게 Changes to be committed 가 됨, commit은 버전이랑 같은 뜻이라고 말씀 드렸었죠
즉 변경사항들이 우리가 깃에게 버전만들어 라고 했을 때 committed가
버전이 될 파일들의 목록을 보여주고 있다. hello1.txt가 그렇다는 것
이때 깃에게 버전 만들어! 라고 하는 명령은
git commit --commit은 제출하다(버전을 제출하다 라는 뜻이 생략된 것 아닐까요)
git commit하고 엔터를 치면 기본에디터가 뜸
거기서 아주 편리하게 수정할 수 있지만
저는 그게 귀찮아서 보통
git commit -m "" 여기서 직접 내용을 적음
git commit -m "Message 1" 하고 엔터를 치면 버전이 생성됨.
> 이때 Staging Area에 있던 hello1.txt가 Repository로 가게됨.
그 다음 git status 해보면
nothing to commit : 버전으로 만들 게 없다.working tree clean : 버전이 되지 않은 수정사항이 있지 않다
버전이 잘 만들어져 있는지 확인하고 싶다면git log --역사를 보고 싶다
Message 1 이라고 하는 버전에 대한 설명이 있는 : 고유한 id값, 누가, 언제나갈땐 q버튼
현 상황 : repository에 마지막 버전이 있고, 그 이후에 수정한 적이 없음
수정을 해보고 git status 하면
Changes not staged for commit: 에 hello1.txt가 뜸 == 스테이지 위에 있지 않은 수정사항이 워킹트리에 있네요!
이때 우리는 git add hello1.txt 하면 스테이지로 올라감
git status하면
확인이 됨
Changes to be committed : 스테이지에 올라가 있다.
이제 버전을 만들 때는 git commit -m "Message 2"
git status 하면 이렇게 확인할 수 있고
git log 는 이렇게 나옴
세가지의 상태Working tree : 수정한 내용이 들어있다.
Staging Area : 수정한 내용 중에 커밋하고 싶은 버전을 만들고 싶은걸 여기에 올린다
Repository : Staging Area에서 commit하면 거기 위에 있는 변경사항들이 저장소에 온다
--------------------------------------------------------------------------------------------------------------------
@5.여러 개의 파일을 버전으로 만들기
파일 하나의 변경사항을 버전으로 만들 수 있다.
근데 보통은 하나의 작업이 여러개 파일의 수정을 담고 있는 경우가 많다
파일 하나 수정하고파일 하나 새로 만들어서 git status해보기
그럼- Changes not staged for commit- Untracked files두개가 나옴두 개의 파일 모두 스테이지 위에 있지 않은 상태라는 공통점이 있다.근데 hello1.txt는 1회 이상 버전관리를 해왔기 때문에 git은 hello1.txt라는 파일을 기억하고 관리하고 있어
hello2.txt는 한번도 버전관리를 한 적이 없기 때문에 git은 얘를 없는 셈 침
그럼 이제 이 상태로 우리의 저장소를 백업한다든지 협업하게되면 hello2.txt라는 파일은 백업이 안됨
백업, 협업하고 싶지 않은 파일은 그냥 Untracked files로 내버려두라고 git은 모든 파일을 자동으로 tracked 하지않음. 자동으로 관리하지 않아
얘를 관리할거야 라고 직접 알려주지 않는 이상엔
모두 Staging Area에 올리기
버전관리 되고 있는 것이든 아닌 것이든 다 git add다.하나는 modified : 마지막 버전 이후에 수정됐다하나는 new file : 신입이다.여튼 둘다 Changes to be committed 상태
그 다음 git commit ~~ 하면되고
git status 하면 nothing to commit, working tree cleangit log하면 잘 나옴
근데 각각의 버전마다 어떤 파일들이 연루 되어 있는지 알고 싶을 땐?구글에 git log files list 뭐 한번 이렇게 검색해 볼까요?
git log --stat을 쓰면 각각 버전별로 어떤 파일이 연루되어있는지 알 수 있습니다. --state의 약자인듯
1 + 는 그 파일이 한줄 추가됐다.밑에는 2개의 파일이, 두 줄이 추가됐다.
=> 하나의 작업에, 하나의 버전에 관련돼있는 여러개의 파일을 그루핑 할 수가 있다.
이런건 파일의 이름을 바꾸는 걸로는 달성하기 까다롭다. 깃을 이용하면 세련되게 이런 문제를 해결할 수 있다.
--------------------------------------------------------------------------------------------------------------------
내 생각 중간점검 :
어떤 폴더에 파일 하나를 두고
git init 을 한 다음 -- git init 이나 git init . 이나 뭐가 다른거지
git status 하니까 바로 Untracked files가 잡힌다
git init을 한 다음부터 변화를 잡는게 아니고 그냥 그 안의 모든 파일에게 관여를 하는 거군
stage에 올리고 파일을 추가를 하거나 커밋을 하거나 할 수 있겠네
파일을 추가를 하면 커밋하기 전이니까 묶여서 커밋이 될거고 커밋이 되면 이제 그 버전은 그 버전인거고
그 행위를 버전으로 묶으면 만약 그 버전이 없어지면 커밋하기 전이 아닌 수정하기 전으로 돌아가겠다 !
그래서 저번에 리버트 하니까 다 날아가 버린게 이거인듯?
버전이 쌓인다고 생각하면 되겠네 수정사항에 대해 거기부터 여기까지의 행위는 이 버전에 담고 이런식으로 그렇지 않을까? 그리고 추적을 안하는 파일은 상관을 안하는 거고
근데 추적을 안하는거랑 버전에 안올리는거랑 뭔 차이지 잘 모르겠네 커밋 0번이랑 커밋 1번의 차이 밖에 없지않나?
어쨌든 파일의 내용이 바뀌었어도 그걸 스테이지에 안올리고 커밋하면 그 변화는 버전에 안담기는거고 그 버전은 딱 다른 파일들의 변경사항만 담겨있는거고 그런식으로 이해하면 될 것 같은데
그리고 버전 중간이 비어있거나 하면 그 위에 덮어씌우지 못하니까(중간이 비어있으니 레고블럭이 안맞듯이) 안맞으면 푸쉬가 안되고 뭐 그런거겠고
--------------------------------------------------------------------------------------------------------------------
@6.버전간의 차이점 비교
제가 정말 좋아하는 명령어 git diff --difference
파일 수정하고 아무것도 안한 상태에서 git diff만 치면
위에 복잡한 표현들은 무시하고마지막 버전과 working tree사이의 차이점을 파악할 수 있어! 빨간색 : (마지막버전은)3이 있었는데 (워킹트리는)3이 없어졌고 초록색 : four라고 하는 내용이 추가됐다.
천만줄이고 파일이 몇백개면 git이 없으면 이런거 절대 알 수 없어작업을 끝내기 전에 == 버전을 만들기 전에, 내가 뭘했는지 반성을 하고 최종적으로 검토를 해볼 수 있는 마지막 기회.이건 버전관리를 쓰는 이유 중 하나, 정말 중요한 효용, git diff
git reset --hard 를 하면 지금까지 우리가 작업한 내용이 휙 하고 사라짐 : 워킹트리의 내용이 사라지나봐 마지막 버전으로 돌아감
마지막 버전 이후에 자기가 작업한 것이 마음에 들지 않을 때 버전관리를 하고 있지 않다면 그걸 과거로 돌리는 것은 정말 어려운 일이다 : 맞지맞지
(reset은 곧 배울 것)
git log -p --patch의 약자
를 치면
Message 3라고 하는 버전은
hello1.txt라고 하는 파일을 갖고 있는데
+3 : 그 파일은 마지막 버전 이후에 3이라고 하는 텍스트가 추가됐고 --a/ b/는 설명 안함
hello2.txt라는 파일도 이 버전에 포함되는데
마지막 버전은 null, 없다는 뜻. 없었고
새롭게 추가된 파일이라는 뜻.
+3 : 그리고 그 추가된 내용에는 3이라는 텍스트가 추가됐다.
지금은 간단해서 별로 효용이 안 느껴지지만, 아주 복잡한 코드라면 코드상, 문서상에서 문제가 생겼을 때 어디에서 문제가 생겼는지 우리가 추적하는데 정말 큰 도움
이런것들이 버전관리를 해서 얻을 수 있는 정말 중요한 효용
버전과 버전, 파일과 파일간의 차이점을 통해 비교할 수 있고, 그 비교를 통해 의사결정을 할 수 있다
여기서 끝내도 되지만 CRUD를 다 해보자 이후 수업에선 Update, Delete를 해볼것
*Read는 status와 log였음
--------------------------------------------------------------------------------------------------------------------
@7.checkout과 시간여행
버전관리 : 코드, 파일, 문서를 수정할 때마다 의미있는 변경점들을 기록하는 것
> 과거로 돌아갔다가 미래로 가는 등 시간을 탐색할 수 있다.
master는 원래 브랜치고 브랜치는 이렇게 설명하면 안되는데 일단 지금은 여러분의 최신 버전을 master라고 생각하세요
HEAD -> master : HEAD가 master를 가리키고 있다는 건, 현재 우리의 상태가 실제 마지막 버전을 가리키고 있다 라는 거라고 생각하시면 됩니다.
그럼 여기서 Message 2 버전의 상태로 가고 싶다면?
1.HEAD를 e706e... 로 시작하는 버전을 가리키게 하면 됨.
: 버전관리하고 있는 디렉토리 전체가 저 버전이 만들어진 시점으로 휙 하고 돌아감
Message 2는 hello1.txt라는 파일만 존재했었음. 숫자 1과 2만 존재했었음.
현재 상태는
과거의 커밋 id를 copy해서
그러면
git log 해보면
master 최신이 없어졌어
> 지워진게 아니래요
HEAD가 이제 저 커밋을 가리키니까 이 상태가 됐다
그 다음 git checkout master 라고 하면 가장 최신이었던 상태로 돌아감
git log 해보면
돌아왔음
과거와 현재를 왔다갔다 하면서 탐색할 수 있다.
--------------------------------------------------------------------------------------------------------------------
@8.보충 수업
사소한데 모르면 불편한 것들
버전 만들 때 : 수정 > add > commit
1.
add할 때 파일명을 직접 지정해도 되지만
git add . 을 찍으면 현재 디렉토리 밑에있는 모든 파일을 add한다
git add 디렉토리명 하면 그 디렉토리 밑에 있는 모든 파일을 add
add를 하지 않고 git commit -am 이거 a가 add의 약자다
git commit -am ".. : add하고 commit 하는것까지 한번에 되는 것
근데 Untracked 파일이 있는 상태에서 commit -am 하면 Untracked 상태인 파일은 add가 자동으로 되지 않는다.
-am의 a는 최초 한번은 add되어 tracked상태가 돼야지만 그 파일을 자동으로 추가해준다.
바로 이걸 통해서 추적하고 싶지 않은 파일이 실수로 추적되는 사고를 방지할 수 있다.
2.
git commit -m 옵션은 커맨드 라인에서 직접 커밋메시지를 적을 때 씀
git commit 만 치면 기본 에디터가 뜸, 생코는 nano로 설정
여러줄을 좀 더 편리하게 작성할 수 있다. 저장하면
여러줄의 커밋메시지
기본 에디터 바꾸는법 : 검색
change git default text editor
git config --global core.editor "vim" 가 나옴.
git config : 설정을 바꾼다
--global : 현재 저장소가 아니라 이 컴퓨터 전체, 로그인한 사용자 전체의 설정을 바꿈
core.editor : 에디터를 바꾸겠다." " 사이에 nano 든 vim 이든 적기, 또는 실행하고 싶은 에디터의 경로를 적으면 됨(이것도 검색해보면 여러가지 방법들이 나와 있다.)
--------------------------------------------------------------------------------------------------------------------
@9.삭제 - git reset
버전을 삭제하는 방법 reset
이 상태에서
Message 3를 지우고
Message 2가 되고 싶다
=> Message 2 버전으로 reset 해야한다.
경계가 헷갈리죠?
Message 2 로 reset한다는 말은 Message 2 를 삭제한다 가 아니라 이 버전이 되겠다!는 말
저 버전으로 reset하겠다 라는 말
git reset --help 치면
--hard 가 나옴
git reset뒤에는 soft, mixed, hard, merge, keep 이런게 있는데mode라고 하는 것임.
내려보면 이런식의 설명
보기만 하고
그냥 생코가 설명해줌, 말로만 할게요 굉장히 복잡해요 이해 지금 할 수 없어요--hard 는 그 버전을 지울 뿐만 아니라 우리가 수정하고 있었던 것 까지도 지워버림, 가장 강력하게 지우는 것
버전만 지우고 수정하고 있던건 살리고 싶다? 살다보면 그럴 수도 있는데그럼 --hard를 soft, mixed 이런걸로 바꾸면 된다 정도만 슬쩍 파악만 하고 넘어가시면 됩니다
이걸 공부하기엔 얻을 수 있는 실익보다 복잡성이 훨씬 높기 때문에 지금은 이정도 느낌만
▽아니 수정하던걸 안지우고 이전 버전을 지우고 그 전 버전으로 돌아간다고? 파일 1, 2 있으면 1만 고친게 버전1일 때 내가 지금 2를 수정중이면 1 고친것만 없애버린다 이 말인가?
또 협업을 할 땐 다른 사람과 공유된 버전에 대해서는 reset을 하면 안돼
공유되기 전 단계의 버전만 reset해야함. 안그러면 엉키는 문제가 생김(지금은 몰라)
▽전 단계의 버전이 더 최신을 말하는 거겠지?
--------------------------------------------------------------------------------------------------------------------
@10.되돌리기 - git revert
reset
revert
말이 엄청 비슷하고 실제로 용도도 비슷하기 때문에 어마어마하게 헷갈림
정보시스템 쪽에선 삭제를 죄악시 하는게 있다.
예를 들면 역사. 자기 마음에 안든다고 삭제하면 후세에게 지탄받음
회계에서 어떤 기록이 있는데 그 기록을 지우면 쇠고랑 참
모든 시스템이 CRUD를 제공하는게 아니라
어떤 시스템은 CR만 제공, UD는 엄격하게 통제하거나 못하게 함
버전도 마찬가지
reset은 특정버전을 지우는 것과 같다
revert를 쓰면 좀 더 세련되게 삭제의 목적과, 보존의 목적을 동시에 달성할 수 있다.
revert는 지금까지 한거 다 합한것 보다 어렵다
이 상태에서reset R3하면 R3버전으로 감R4를 revert하면 R3로 감, R4의 commit id 가 필요함
▽R3 commit 하고 수정하고 R4 commit 했어 여기서 R4를 revert하면 수정한게 다 날아감
revert를 하게 되면 commit 메시지를 작성하라고 기본 설정돼 있는 에디터가 뜰 것
를 하면
▽오 revert도 커밋 메시지를 작성하는구나 : 저장할 수가 있구나
왜 revert시키는지 이런것도 적어주면 좋다
revert메시지를 작성하면 커밋이 됨
이렇게 기존에 있는 R4가 사라지지 않고, 새로 commit이 됨
기존에 commit은 내버려두고, 이 commit에서의 변화를 취소한 것임. == R3가 됨
git log -p 하면 확인할 수 있음
이제 Message 1 으로 돌아가고 싶다? revert 방식으로
Message 2 를 revert하면 Message 1로 돌아간다? 충돌이 일어남revert R4 > revert R3 > revert Message 2 이렇게 순차적으로 해줘야 충돌이 발생하지 않는다
왜냐? Message 1이 되고 싶으면 Message 2이전의 변화들을 되돌리기 하면 되는데revert는 Message 2 이후의 모든 변화를 되돌리는게 아니라 Message 2를 할 때의 변화만을 되돌리는 게 git revert이기 때문에 한번에 revert Message 2를 하면 Message 2 이후의 변화인 R3, R4를 git 입장에선 이거 어떻게 해야하지 생각을 하게됨 : 제가 이걸 실행하게 되면 R3, R4를 유실하게 되기 때문에 할 수 없습니다! 알아서 하세요 = conflict발생. 처리하기 까다롭다
--------------------------------------------------------------------------------------------------------------------
@수업을 마치며
버전관리의 핵심은 비교. 비교를 통해서 과거를 되돌아볼 수 있다는 것이 버전관리의 핵심
diff tool로 검색해보고 얘네들을 이용해서 차이점을 보다 더 정교하게 보기.
정확한 의사결정을 내리고 현재상황을 현재상황을 신속하게 파악하는데 정말 큰 도움이 됨.
버전관리를 하지 말아야할 파일이 있을 땐
.gitignore라는 파일을 만들고 거기에 파일의 이름을 적으면 됨.
파일을 편집하다보면 그 프로그램이 필요에 따라 임시 파일을 만드는 경우가 있다.
또 나혼자 보기 위해서 특정파일에 비밀번호 같은걸 메모하고 있긴 하지만 그걸 버전관리하고 싶진 않을수도.
.gitignore검색하면 관련 내용이 나옴.
깃의 혁신적인 면 중에 하나는 branch 환상적인 도구
평행우주처럼 우리의 저장소를 여러 가지 상태로 공존할 수 있게 만듦.
내가 보고서를 만들었는데 이 보고서를 기반으로 Google, Apple, MS 등의 회사에 맞게 조금씩 조금씩 다른 내용들로 수정해서 제공해야될때, 아마 여러분은 저장소 전체를 복사해서 디렉토리를 만들고 각각을 작업하려고 할 것
브랜치를 이용한다면 저장소의 이름을 더럽히지 않고, 하나의 저장소에서 다양한 작업 진행가능.
각각의 버전을 식별하는 식별자로 commit id라는 것이 사용되는데 기억하지 적절하지 않다.
->적당한 이해하기 쉬운 이름을 붙일 수 있다. tag. 이걸 이용해서 쉽게 중요한 버전으로 찾아갈 수 있다
backup
backup을 하지 않는다면 내 정보를 언젠간 유실하겠다고 선언한 것과 같다.
Git은 자체적으로 매우 편리하고 안전한 백업장치를 갖고 있다.
클릭한번으로 지금까지 작업한걸 인터넷에 업로드해서 백업할 수 있다.
그걸 또 다운로드 받아서 바로 작업을 시작할 수 있어.
> 이거 배우기전까지도 위험하니까 dropbox, google drive, one drive등에 꼭 백업을 해놔
backup 너머에 협업이 있다.
- 너무 많은 것을 배우려고 조급해서 어렵게 느껴질 수도 있다
- 나의 문제는 별 거 아닌데 훨씬 더 어려운 도구를 도입하려고 할 때 어렵게 느껴질 수도 있다
내 지옥을 버전관리로 빠져나오는 법을 배웠어
더많은 것을 공부하기 전에 최대한 오래 머물면서 배운 것을 사용하시면 좋겠습니다.
그럼 어느시점에 그 다음 고비를 넘을 수 있는 체력, 조건이 마련되면 그때 수월하게 어렵지않게 희망차게 고개를 넘을 수 있게 될 것입니다.
'생활코딩 Git' 카테고리의 다른 글
Git4 - SourceTree (4)Collaboration (0) 2021.11.08 Git3 - SourceTree (3)Backup (0) 2021.11.08 Git3 - SourceTree (2)branch & conflict (0) 2021.11.08 Git2 - SourceTree (1)Version Control (0) 2021.11.08 Git1 (0) 2021.10.05