인턴으로 일하면서 다같이 git을 쓰다 보니 학교 과제나 혼자서 쓰는 git과는 다른 일이 자주 일어나고 그에 따른 새로운 깃 활용 법을 익혀가는 느낌이네요 늦은 감이 있지만 여기에 하나하나 적어두려 합니다.
기초적인 코드 수정사항 반영-커밋-푸쉬 보다는 여러가지 깨알 같은 팁들을 적어두려 합니다

깃헙에다가 사고를 안 치는게 가장 좋지만 맨날 사고를 치니 이런 것들만 찾아보게 되네요

이렇게 3개의 파일이있는 레포지토리를 예시로 작성하겠습니다.

Commit메시지수정 또는 파일 추가 (Push 전/후 주의점)

Commit의 Push는 생각보다 아주 신중해야 한다는 점을 많이 느끼게 되었습니다.
Push라는 명령을 하는 순간부터 git은 여러가지로 머리가 아파지더라구요
git status로 파일을 보고 필요한 파일만을 add 한 다음에 반드시 diff 명령 등으로 수정사항을 확인하고 누락사항이 없나 꼼꼼하게 확인 후 push하는게 가장 중요합니다.
force push로 수정할 수 있으나 force push했다는 기록이 남기 때문에 선호하지 않는 경우도 있으며 force로 덮어 씌울 때 진짜 본인이 정확히 무엇을 수정하고 강제로 덮어쓰는지 정확히 파악하지 못하면 정말 골치아픕니다…

push 전

git commit --amend

누락한 파일이 있으면 git add 명령으로 해당 파일을 추가하고 위의 명령어를 입력하면 commit message의 수정 창이 뜹니다. 필요한 경우 commit message의 수정을 해 주시면 반영이 됩니다.

file1만 추가하여 commit을 하였습니다.
여기에 file2를 추가하여 commit message를 수정하겠습니다.

이후 vim창에서 commit message를 Typo Fixed로 수정하였습니다

수정하기 전 로그 수정 후 로그

파일 추가를 전부 취소하거나 좀 크게 갈아 엎어야 할 경우에는

git reset --soft HEAD~1

이후 다시 파일들을 정비하셔서 git commit –amend를 해주시면 됩니다.
단 HEAD보다 하나 전의 commit 이 존재해야합니다. 즉 두번째 이후의 commit에 대하여 사용 가능합니다.

reset 의 soft와 hard의 차이

soft는 수정사항은 그대로 둡니다. hard는 모든 수정사항도 discard합니다.

push 후

이미 push했을 경우에는 commit 을 수정하신 다음에 push -f 로 강제 push를 해야합니다. 다만 해당 영향을 정확히 이해하지 못할 경우 해당 레포의 코드를 복구불가하게 덮어씌우거나 Commit log가 오염될 수 있습니다.

특정 브랜치와의 diff ( 전체 / 특정 파일 )

수정을 하기는 했는데 정확히 어디를 수정했는지 혹시 이상하게 바뀐 곳은 없는지 확인을 하기 위해서 사용합니다.
수정사항이 많아지다 보면 늘 불안해지죠 특히 어딘가에 디버깅용 코드를 넣어둔게 살아 있지는 않을까 갑자기 어디 파일이 확 변해있지는 않을까 하는 걱정이 들 때 사용합니다

git diff [target] [source]

먼저 추가 브랜치를 준비하여 file1,2,3에 대해 추가적인 글을 입력하였습니다. 이걸로 이 branch2는 master branch와 차이가 생깁니다.
*master보다 main이라는 이름을 쓰는 것이 바람직하나 기본이 master 였으므로 그대로 진행하였습니다.

source가 target에 비해 어디가 추가되고 지워졌는지를 보여줍니다
예시로는

git diff origin/main

은 remote의 main브랜치와 현재 로컬 브랜치의 차이를 전부 출력합니다.

로컬 master branch와의 diff 출력

특정 파일만 확인하고 싶을 경우에는

특정파일 또는 디렉토리와

git diff [target]:[location of file] [location of file at local]

예시

git diff origin/main:src/target src/target

이러면 특정 디렉토리, 특정파일 끼리만의 비교가 가능합니다

특정 branch에 대해서 수정된 파일이름만 확인 하고 싶은 경우에는 –name-only 옵션을 사용합니다

바뀐 파일 이름만 확인하기

git diff --name-only origin/main

특정 directory또는 파일을 특정 branch로부터 copy

이것 저것 작업하다 보면 건들면 안되는 부분이 막 바뀌어 있을 경우가 있습니다.

내용이 안 바뀌더라도 저 같은 경우에는 CRLF를 LF로 바꿔주는 프로그램을 돌렸더니 갑자기 바꿔서는 안될 디렉토리가 전부 바뀌어 버리고 하는 경우도 있었으며 디버깅용 코드를 추가하고 지우는 과정에서 공백 등이 꼬여서 필요없는 파일이 추가되어 있는 경우가 있었습니다.

이 경우에는 작동에 영향이 없더라도 pull request의 changed file을 오염시켜 보기 힘들게 만들고 나중에 main으로 merge 된 다음에도 다른 분들이 pull을 하는 과정에서 conflict나 다른 예상치 못한 에러를 유발할 수 있습니다.

그런데 이걸 다 손으로 돌려둘 수 없어서 그냥 특정 브랜치의 이 폴더를 다시 copy해 오고 싶은 경우가 있지요.

git checkout은 브랜치를 바꾸는 것 뿐만이아니라 특정 파일만 해당 branch에서 가져오도록 지정이 가능합니다

git checkout [branch_name] [file/dir_name]

master branch에서 file1만 체크아웃하니 master branch와 같은 공백으로 돌아왔다.

Commit log가 너무 지저분해요!

깃헙쓰면서 누구나 한번 쯤은 겪는 아니 한번만 겪음 다행인 문제 아닐까 싶네요
다른 사람들의 수정을 반영하다가 다른사람이 지저분하게 한 커밋로그가 밀려 들어오거나 rebase랑 pull을 반복하다가 어느 순간 main branch의 커밋로그가 밀려들어오거나 하면 끔찍한 상황이 발생합니다.

특히 커밋로그를 깨끗하게 관리하는 상황에서는 이러면 한 소리를 듣기도 하는데요..

git log

먼저 git log로 커밋 로그를 확인합니다 그리고 HEAD (최신 커밋)에서 몇번 째 까지를 살릴 지를 정합니다. 해당 기록 사이에 외부 브랜치의 commit들이 포함되어있어도 괜찮습니다. 자신이 반영하고싶은 커밋이 있는 곳까지를 생각하여 그곳이 HEAD에서 몇번째인지 카운트합니다.

git rebase -i HEAD~(숫자)

interactive모드로 rebase를 합니다. 그럼 VIM이나 NANO같은 기본 텍스트 에디터를 볼 수 있습니다. ( Git bash 또는 Linux terminal 기준 )

pick hash commit-message 순으로 나열된 창에서

pick을 원하는 메시지로 변경하시면 됩니다.

p - > 해당 커밋을 그대로 둔다
r -> 해당 커밋을 그대로 두지만 뒤의 메시지는 변경하겠다
e -> rebase중에 이 커밋을 작업하기전에 멈춰라 난 amend를 통해 추가적인 수정을 하겠다
s -> 이전 commit과 합쳐버려라 하지만 메시지는 남김
f -> 이 커밋은 메시지도 남기지 말고 합쳐버려라 ( 단 -C 옵션과 사용시 이전 커밋의 메시지를 지우고 f 가 붙은 커밋의 메시지를 사용하며 -c를 사용할 경우 추가적인 수정이 가능 )

등 옵션을 적절히 사용하여 커밋 기록들을 바꿔줍니다

마지막으로 해당 rebase를 진행시킨 후 push를 합니다.

만약 이미 push를 한 commit을 포함하여 수정하고 싶은 경우에는 push -f 를 하셔야합니다.

여기 지저분한 커밋로그가 있습니다. push하면 곤란할 내용까지 있네요. 이걸 모르고 push 해버렸다고 생각하면 끔찍합니다.

git rebase -i HEAD~4

를 입력하면 아래와 같은 창이 뜹니다.

헉 수정한 vim 캡쳐가 날아갔네요 ㅜㅜ 텍스트로 대체합니다

pick 9fa5ddf branch2
s 9832215 dirty commit
p 1217366 commmmmmmmit
f 1d2eb3a boring task www

와 같이 사용하였습니다. 이후 해당 텍스트파일에서 나오시면 rebase를 진행하여 다음과 같은 로그가 됩니다.

squash옵션을 사용할 때 기본적으로 수정창이 뜹니다. 기본적으로는 다음 commit의 메시지와 융합되어 적혀있습니다.

만약 conflict가 발생하면 잘 해결한 후에 force push를 진행합니다

commit할 수정사항이 아닌데 애가 commit한 다음에 진행하래요 - git stash

작업 중에 갑자기 main branch나 참조 brranch가 업데이트 되어서 rebase 또는 pull을 할 상황인데 수정사항이 있으면 이걸 못하게 막죠.
별 수정 사항이 없으면 reset –hard 등으로 해결할 수도 있지만 수정 중이면 곤란합니다 commit message에 “pull 하려고 백업커밋좀.. " 이라고 하기도 그렇구요
이 때 force로 pull이나 rebase를 하시면 작업 증발 등 영 좋지 않은 일이 일어나기 쉽습니다.
git stash를 활용하면 임시적으로 이 파일들을 피난시킬 수 있습니다.

git status

로 변경사항을 확인하고 commit에 쓰듯이 유지해야 할 수정사항 들을 add 커멘드로 추가합니다

git stash

를 입력하면 이 친구들은 commit은 아니지만 임시 commit과 같이 임시적으로 저장되며 수정 전으로 rollback 합니다.

이후 해당 필요한 작업들을 진행합니다.
진행이 완료되었으면

git stash pop

을 하면 stash했던 수정사항을 하나씩 꺼낼 수 있습니다. 해당 과정은 사실상 merge와 같은 원리라 conflict가 발생하기도 하니 적절히 수정하면서 진행해 주시면 됩니다.

error: Your local changes to the following files would be overwritten by checkout

file3에 추가적인 데이터를 입력하고 add를 한 상태에서 checkout을 하려하니 commit을 하라고 합니다.
add를 풀고 checkout하자니 목적branch가오염될까봐 두렵고.. 그렇다고 discard하자니 수정한 것이 아깝고 commit하자니 너무 사소하여 나중에 commit log 수정이 필요할 것 같은 경우가 있습니다.

이 경우 해당 파일들을 add한 상태에서 git stash를 통해 내용을 임시저장 시킨 후에 change들을 discard할 수 있습니다. 이제 성공적으로 branch이동이 가능해졌습니다!

git stash pop을 통하여 수정사항을 복구하였습니다.