1. 초보자를 위한 Git 상세 가이드

오늘 우리는 Git이라는 버전 제어 시스템에 대해 이야기할 것입니다.

이 도구를 알고 이해하지 않고는 본격적인 프로그래머가 될 수 없습니다. 물론 지속적으로 사용하기 위해 모든 Git 명령과 기능을 머릿속에 간직할 필요는 없습니다. 일어나는 모든 일을 이해하는 데 도움이 되는 일련의 명령을 알아야 합니다.

힘내 기초

Git은 우리 코드의 분산 버전 제어 시스템입니다. 왜 필요한가요? 팀에는 작업을 관리하기 위한 일종의 시스템이 필요합니다. 시간 경과에 따라 발생하는 변경 사항을 추적하는 데 필요합니다.

즉, 어떤 파일이 어떻게 변경되었는지 단계별로 확인할 수 있어야 합니다. 이는 단일 작업의 컨텍스트에서 변경된 사항을 조사하여 변경 사항을 되돌릴 수 있을 때 특히 중요합니다.

다음과 같은 상황을 상상해 봅시다. 작동하는 코드가 있고 그 안의 모든 것이 양호하지만 무언가를 개선하거나 조정하기로 결정합니다. 큰 문제는 아니지만 우리의 "개선"으로 인해 프로그램 기능의 절반이 손상되어 작업이 불가능해졌습니다. 그래서 지금 무엇? Git이 없었다면 모든 것이 원래 어땠는지 기억하려고 몇 시간 동안 앉아서 생각해야 할 것입니다. 그러나 Git을 사용하면 커밋을 롤백하기만 하면 됩니다.

또는 두 명의 개발자가 동시에 자신의 코드를 변경하는 경우 어떻게 해야 합니까? Git이 없으면 원본 코드 파일을 복사하여 별도로 수정합니다. 둘 다 기본 디렉토리에 변경 사항을 추가하려는 경우가 있습니다. 이 경우 어떻게 합니까?

Git을 사용한다면 그런 문제는 없을 것입니다.

힘내 설치

컴퓨터에 Java를 설치해 봅시다. 이 프로세스는 운영 체제마다 약간 다릅니다.

Windows에 설치

평소와 같이 exe 파일을 다운로드하여 실행해야 합니다. 여기에서는 모든 것이 간단합니다. 첫 번째 Google 링크를 클릭하고 설치를 수행하면 됩니다. 이를 위해 Windows에서 제공하는 bash 콘솔을 사용합니다.

Windows에서는 Git Bash를 실행해야 합니다. 시작 메뉴에 표시되는 방식은 다음과 같습니다.

이제 작업할 수 있는 명령 프롬프트입니다.

Git을 열기 위해 매번 프로젝트가 있는 폴더로 이동하지 않으려면 필요한 경로에서 마우스 오른쪽 버튼을 사용하여 프로젝트 폴더에서 명령 프롬프트를 열 수 있습니다.

리눅스에 설치하기

일반적으로 Git은 Linux 배포판의 일부이며 원래 Linux 커널 개발용으로 작성된 도구이기 때문에 이미 설치되어 있습니다. 그러나 그렇지 않은 상황이 있습니다. 확인하려면 터미널을 열고 git --version을 작성해야 합니다. 이해할 수 있는 답변을 얻으면 아무것도 설치할 필요가 없습니다.

터미널을 열고 설치합니다. Ubuntu의 경우 다음과 같이 작성해야 합니다. sudo apt-get install git. 이제 모든 터미널에서 Git을 사용할 수 있습니다.

macOS에 설치

여기서도 Git이 이미 있는지 먼저 확인해야 합니다(위 참조, Linux와 동일).

가지고 있지 않은 경우 가장 쉬운 방법은 최신 버전을 다운로드하는 것입니다 . Xcode가 설치되어 있으면 Git이 자동으로 설치됩니다.

힘내 설정

Git에는 작업을 제출할 사용자에 대한 사용자 설정이 있습니다. 커밋이 생성될 때 Git이 Author 필드에 대해 이 정보를 사용하기 때문에 이것은 이치에 맞고 필요합니다.

다음 명령을 실행하여 모든 프로젝트에 대한 사용자 이름과 비밀번호를 설정하십시오.

git config --global user.name "Ivan Ivanov" git config --global user.email ivan.ivanov@gmail.com

특정 프로젝트(예: 개인 프로젝트)의 작성자를 변경해야 하는 경우 "--global"을 제거할 수 있습니다. 이것은 우리에게 다음을 줄 것입니다:

git config user.name "이반 이바노프" git config user.email ivan.ivanov@gmail.com

약간의 이론

주제에 대해 자세히 알아보려면 몇 가지 새로운 단어와 동작을 소개해야 합니다. 그렇지 않으면 이야기할 것이 없습니다. 물론 이것은 영어에서 우리에게 오는 전문 용어이므로 괄호 안에 번역을 추가하겠습니다.

어떤 말과 행동?

  • Git 저장소
  • 저지르다
  • 나뭇가지
  • 병합
  • 갈등
  • 당기다
  • 푸시
  • 일부 파일(.gitignore)을 무시하는 방법

등등.

Git의 상태

Git에는 이해하고 기억해야 하는 몇 가지 조각상이 있습니다.

  • 추적되지 않은
  • 수정
  • 일부러 꾸민
  • 헌신적인

이것을 어떻게 이해해야 할까요?

코드가 포함된 파일에 적용되는 상태입니다. 즉, 수명 주기는 일반적으로 다음과 같습니다.

  • 생성되었지만 아직 저장소에 추가되지 않은 파일은 "추적되지 않음" 상태입니다.
  • Git 리포지토리에 이미 추가된 파일을 변경하면 상태가 "수정됨"이 됩니다.
  • 변경한 파일 중에서 필요한 파일(예: 컴파일된 클래스가 필요 없음)을 선택하면 이러한 클래스가 "스테이지" 상태로 변경됩니다.
  • 준비 상태의 준비된 파일에서 커밋이 생성되어 Git 리포지토리로 이동합니다. 그 이후에는 "스테이지" 상태의 파일이 없습니다. 그러나 여전히 상태가 "수정됨"인 파일이 있을 수 있습니다.

다음과 같이 표시됩니다.

커밋이란 무엇입니까?

커밋은 버전 제어와 관련하여 주요 이벤트입니다. 여기에는 커밋이 시작된 이후에 변경된 모든 내용이 포함됩니다. 커밋은 단일 연결 목록처럼 함께 연결됩니다.

특히 첫 번째 커밋이 있습니다. 두 번째 커밋이 생성되면 두 번째 커밋은 첫 번째 커밋 다음에 무엇이 오는지 알고 있습니다. 그리고 이러한 방식으로 정보를 추적할 수 있습니다.

커밋에는 메타데이터라고 하는 자체 정보도 있습니다.

  • 커밋을 찾는 데 사용할 수 있는 커밋의 고유 식별자
  • 커밋을 만든 작성자의 이름
  • 커밋이 생성된 날짜
  • 커밋 중에 수행된 작업을 설명하는 주석

다음과 같이 표시됩니다.

지점이란 무엇입니까?

분기는 일부 커밋에 대한 포인터입니다. 커밋은 어떤 커밋이 선행하는지 알고 있기 때문에 분기가 커밋을 가리키면 이전 커밋도 모두 적용됩니다.

따라서 동일한 커밋을 가리키는 지점을 원하는 만큼 많이 가질 수 있다고 말할 수 있습니다.

작업은 브랜치에서 발생하므로 새 커밋이 생성되면 브랜치는 포인터를 더 최근 커밋으로 이동합니다.

힘내 시작하기

원격 저장소뿐만 아니라 로컬 저장소로도 작업할 수 있습니다.

필요한 명령을 연습하기 위해 자신을 로컬 리포지토리로 제한할 수 있습니다. 모든 프로젝트 정보를 .git 폴더에만 로컬로 저장합니다.

원격 저장소에 대해 이야기하는 경우 모든 정보는 원격 서버 어딘가에 저장됩니다. 프로젝트의 복사본만 로컬에 저장됩니다. 로컬 복사본에 대한 변경 사항을 원격 저장소로 푸시(git push)할 수 있습니다.

여기와 아래의 논의에서 우리는 콘솔에서 Git 작업에 대해 이야기하고 있습니다. 물론 일종의 GUI 기반 솔루션(예: IntelliJ IDEA)을 사용할 수 있지만 먼저 실행 중인 명령과 그 의미를 파악해야 합니다.

로컬 리포지토리에서 Git 작업

로컬 리포지토리를 만들려면 다음을 작성해야 합니다.

자식 초기화

그러면 콘솔의 현재 디렉토리에 숨겨진 .git 폴더가 생성됩니다.

.git 폴더는 Git 리포지토리에 대한 모든 정보를 저장합니다. 삭제하지 마세요 ;)

다음으로 파일이 프로젝트에 추가되고 "추적되지 않음" 상태가 지정됩니다. 작업의 현재 상태를 확인하려면 다음과 같이 작성하십시오.

자식 상태

우리는 마스터 브랜치에 있으며 다른 브랜치로 전환할 때까지 여기에 남아 있습니다.

이것은 변경되었지만 아직 "스테이지" 상태에 추가되지 않은 파일을 보여줍니다. "staged" 상태에 추가하려면 "git add"라고 작성해야 합니다. 여기에 몇 가지 옵션이 있습니다. 예를 들면 다음과 같습니다.

  • git add -A — 모든 파일을 "staged" 상태로 추가
  • 자식 추가 . — 이 폴더와 모든 하위 폴더의 모든 파일을 추가합니다. 본질적으로 이전 것과 동일합니다.
  • git add <file name> — 특정 파일을 추가합니다. 여기에서 정규식을 사용하여 일부 패턴에 따라 파일을 추가할 수 있습니다. 예를 들어, git add *.java: 이는 확장자가 java인 파일만 추가하려는 것을 의미합니다.

처음 두 옵션은 분명히 간단합니다. 최신 추가 기능으로 상황이 더욱 흥미로워지므로 다음과 같이 작성해 보겠습니다.

자식 추가 *.txt

상태를 확인하기 위해 이미 알려진 명령을 사용합니다.

자식 상태

여기에서 정규 표현식이 올바르게 작동했음을 알 수 있습니다. test_resource.txt는 이제 "스테이지" 상태입니다.

그리고 마지막으로 로컬 저장소 작업을 위한 마지막 단계입니다(원격 저장소 작업 시 하나 더 있습니다 ;)) — 새 커밋 생성:

git commit -m "모든 txt 파일이 프로젝트에 추가되었습니다"

다음은 브랜치의 커밋 히스토리를 보기 위한 훌륭한 명령입니다. 그것을 활용하자:

자식 로그

여기에서 첫 번째 커밋을 생성했으며 명령줄에서 제공한 텍스트가 포함되어 있음을 확인할 수 있습니다. 이 텍스트는 이 커밋 중에 수행된 작업을 가능한 한 정확하게 설명해야 한다는 점을 이해하는 것이 매우 중요합니다. 이것은 앞으로 여러 번 우리에게 도움이 될 것입니다.

아직 잠들지 않은 호기심 많은 독자는 GitTest.java 파일에 무슨 일이 일어났는지 궁금할 것입니다. 지금 바로 알아봅시다. 이를 위해 다음을 사용합니다.

자식 상태

보시다시피 여전히 "추적되지 않은" 상태이며 대기 중입니다. 하지만 프로젝트에 전혀 추가하고 싶지 않다면 어떻게 해야 할까요? 때때로 그런 일이 발생합니다.

좀 더 흥미롭게 만들기 위해 이제 test_resource.txt 파일을 변경해 보겠습니다. 거기에 텍스트를 추가하고 상태를 확인합시다.

자식 상태

여기에서 "추적되지 않음" 상태와 "수정됨" 상태의 차이를 명확하게 확인할 수 있습니다.

GitTest.java는 "추적되지 않음"이고 test_resource.txt는 "수정됨"입니다.

수정된 상태의 파일이 있으므로 변경 사항을 검사할 수 있습니다. 이는 다음 명령을 사용하여 수행할 수 있습니다.

자식 차이

즉, 내가 텍스트 파일에 추가한 내용을 여기에서 명확하게 볼 수 있습니다. Hello World!

변경 사항을 텍스트 파일에 추가하고 커밋을 생성해 보겠습니다.

자식 추가 test_resource.txt
git commit -m “안녕하세요! test_resource.txt로”

모든 커밋을 보려면 다음과 같이 작성하십시오.

자식 로그

보시다시피 이제 두 개의 커밋이 있습니다.

동일한 방식으로 GitTest.java를 추가합니다. 여기에는 설명이 없으며 명령만 있습니다.

자식 추가 GitTest.java
git commit -m "GitTest.java 추가"
자식 상태

.gitignore 작업

분명히 우리는 저장소에 소스 코드만 유지하고 다른 어떤 것도 유지하지 않기를 원합니다. 그래서 무엇이 더있을 수 있습니까? 최소한 개발 환경에서 생성된 컴파일된 클래스 및/또는 파일.

Git에게 무시하라고 지시하려면 특수 파일을 만들어야 합니다. 방법: 프로젝트의 루트에 .gitignore라는 파일을 만듭니다. 이 파일의 각 줄은 무시할 패턴을 나타냅니다.

이 예에서 .gitignore 파일은 다음과 같습니다.

*.class
target/
*.iml
.idea/

한 번 보자:

  • 첫 번째 줄은 확장자가 .class인 모든 파일을 무시하는 것입니다.
  • 두 번째 줄은 "대상" 폴더와 포함된 모든 항목을 무시하는 것입니다.
  • 세 번째 줄은 확장자가 .iml인 모든 파일을 무시하는 것입니다.
  • 네 번째 줄은 .idea 폴더를 무시하는 것입니다.

예제를 사용해 봅시다. 작동 방식을 확인하기 위해 컴파일된 GitTest.class를 프로젝트에 추가하고 프로젝트 상태를 확인합니다.

자식 상태

분명히 우리는 실수로 컴파일된 클래스를 프로젝트에 추가하고 싶지 않습니다(git add -A 사용). 이렇게 하려면 .gitignore 파일을 만들고 앞에서 설명한 모든 항목을 추가합니다.

이제 커밋을 사용하여 .gitignore 파일을 프로젝트에 추가해 보겠습니다.

자식 추가 .gitignore
git commit -m ".gitignore 파일 추가"

그리고 이제 진실의 순간: 우리는 Git 저장소에 추가하고 싶지 않은 "추적되지 않은" 컴파일된 클래스 GitTest.class를 가지고 있습니다.

이제 .gitignore 파일의 효과를 확인해야 합니다.

자식 상태

완벽한! .gitignore +1 :)

브랜치 작업

당연히 하나의 브랜치에서 작업하는 것은 단독 개발자에게는 불편하고 한 팀에 여러 사람이 있을 때는 불가능합니다. 이것이 우리에게 지점이 있는 이유입니다.

분기는 커밋에 대한 이동 가능한 포인터일 뿐입니다.

이 파트에서는 ​​서로 다른 브랜치에서 작업하는 방법을 살펴보겠습니다. 한 브랜치에서 다른 브랜치로 변경 사항을 병합하는 방법, 발생할 수 있는 충돌 등이 있습니다.

저장소의 모든 브랜치 목록을 보고 자신이 속한 브랜치를 이해하려면 다음과 같이 작성해야 합니다.

자식 분기 -a

마스터 분기가 하나만 있는 것을 볼 수 있습니다. 그 앞의 별표는 우리가 그 안에 있음을 나타냅니다. 그건 그렇고, "git status" 명령을 사용하여 우리가 속한 분기를 찾을 수도 있습니다.

그런 다음 가지를 만드는 몇 가지 옵션이 있습니다(더 있을 수 있습니다. 제가 사용하는 옵션입니다).

  • 우리가 있는 지점을 기반으로 새 지점을 만듭니다(99%의 경우).
  • 특정 커밋을 기반으로 분기 생성(사례의 1%)

특정 커밋을 기반으로 분기를 만들어 봅시다

커밋의 고유 식별자에 의존합니다. 그것을 찾기 위해 다음과 같이 작성합니다.

자식 로그

" added hello world..."라는 주석으로 커밋을 강조 표시했습니다. 고유 식별자는 6c44e53d06228f888f2f454d3cb8c1c976dd73f8입니다. 이 커밋에서 시작하는 "개발" 분기를 만들고 싶습니다. 이를 위해 다음과 같이 작성합니다.

git checkout -b 개발 6c44e53d06228f888f2f454d3cb8c1c976dd73f8

마스터 브랜치의 처음 두 커밋만으로 브랜치가 생성됩니다. 이를 확인하기 위해 먼저 다른 브랜치로 전환하고 커밋 수를 확인합니다.

자식 상태
자식 로그

예상대로 커밋이 두 개 있습니다. 그런데 여기 흥미로운 점이 있습니다. 이 분기에는 아직 .gitignore 파일이 없으므로 컴파일된 파일(GitTest.class)이 이제 "추적되지 않음" 상태로 강조 표시됩니다.

이제 다음과 같이 작성하여 분기를 다시 검토할 수 있습니다.

자식 분기 -a

"마스터"와 "개발"의 두 가지 분기가 있음을 알 수 있습니다. 우리는 현재 개발 중입니다.

현재 브랜치를 기반으로 브랜치를 만들어 봅시다.

분기를 만드는 두 번째 방법은 다른 분기에서 만드는 것입니다. 마스터 브랜치를 기반으로 브랜치를 생성하려고 합니다. 먼저 전환해야 하며 다음 단계는 새 항목을 만드는 것입니다. 한 번 보자:

  • git checkout master — 마스터 브랜치로 전환
  • git status — 실제로 마스터 브랜치에 있는지 확인

여기에서 마스터 브랜치로 전환하고 .gitignore 파일이 적용되고 컴파일된 클래스가 더 이상 "추적되지 않음"으로 강조 표시되지 않는 것을 볼 수 있습니다.

이제 마스터 브랜치를 기반으로 새 브랜치를 생성합니다.

git checkout -b 기능/업데이트-txt-파일

이 분기가 "마스터"와 같은지 확실하지 않은 경우 "git log"를 실행하고 모든 커밋을 보면 쉽게 확인할 수 있습니다. 네 개가 있어야합니다.

갈등 해결

충돌이 무엇인지 알아보기 전에 한 가지를 다른 가지로 병합하는 것에 대해 이야기해야 합니다.

이 그림은 한 분기를 다른 분기로 병합하는 과정을 보여줍니다.

여기에 본점이 있습니다. 어느 시점에서 보조 분기가 기본 분기에서 생성된 다음 수정됩니다. 작업이 완료되면 한 분기를 다른 분기에 병합해야 합니다.

이 예에서는 feature/update-txt-files 분기를 만들었습니다. 지점 이름에서 알 수 있듯이 텍스트를 업데이트하고 있습니다.

이제 이 작업에 대한 새 커밋을 생성해야 합니다.

자식 추가 *.txt
git commit -m "업데이트된 txt 파일"
자식 로그

이제 feature/update-txt-files 분기를 master로 병합하려면 master로 이동하여 "git merge feature/update-txt-files"를 작성해야 합니다.

자식 체크 아웃 마스터
자식 병합 기능/업데이트-txt-파일
자식 로그

그 결과 이제 master 분기에는 feature/update-txt-files에 추가된 커밋도 포함됩니다.

이 기능이 추가되었으므로 기능 분기를 삭제할 수 있습니다. 이를 위해 다음과 같이 작성합니다.

git branch -D 기능/업데이트-txt-파일

상황을 복잡하게 만들어 보겠습니다. 이제 txt 파일을 다시 변경해야 한다고 가정해 보겠습니다. 그러나 이제 이 파일은 마스터 브랜치에서도 변경됩니다. 즉, 병렬로 변경됩니다. Git은 새 코드를 마스터 브랜치에 병합하려고 할 때 수행할 작업을 파악할 수 없습니다.

master를 기반으로 새 분기를 만들고 text_resource.txt를 변경하고 이 작업에 대한 커밋을 만듭니다.

git checkout -b 기능/추가 헤더

... 파일을 변경합니다.

자식 추가 *.txt
git commit -m "txt에 헤더 추가"

마스터 브랜치로 이동하고 기능 브랜치에서와 같은 줄에서 이 텍스트 파일도 업데이트합니다.

자식 체크 아웃 마스터

… test_resource.txt를 업데이트했습니다.

자식 추가 test_resource.txt
git commit -m "txt에 마스터 헤더 추가"

이제 가장 흥미로운 점은 기능/추가 헤더 분기에서 마스터로 변경 사항을 병합해야 한다는 것입니다. 우리는 마스터 브랜치에 있으므로 다음과 같이 작성하기만 하면 됩니다.

자식 병합 기능/추가 헤더

그러나 그 결과 test_resource.txt 파일에서 충돌이 발생합니다.

여기에서 Git이 이 코드를 병합하는 방법을 스스로 결정할 수 없음을 알 수 있습니다. 충돌을 먼저 해결한 다음 커밋을 수행해야 함을 알려줍니다.

좋아요. 텍스트 편집기에서 충돌이 있는 파일을 열고 다음을 확인합니다.

여기서 Git이 수행한 작업을 이해하려면 변경 내용과 위치를 기억한 다음 비교해야 합니다.

  1. 마스터 브랜치의 이 줄에 있었던 변경 사항은 "<<<<<<< HEAD"와 "=======" 사이에 있습니다.
  2. feature/add-header 분기에 있었던 변경 사항은 "======="와 ">>>>>>> feature/add-header" 사이에 있습니다.

이것이 Git이 파일의 이 위치에서 병합을 수행하는 방법을 알아낼 수 없다고 말하는 방법입니다. 이 섹션을 서로 다른 분기의 두 부분으로 나누고 병합 충돌을 직접 해결하도록 초대합니다.

그럴 수 있지. 나는 "헤더"라는 단어 만 남기고 모든 것을 제거하기로 대담하게 결정했습니다.

변경 상태를 살펴보겠습니다. 설명이 약간 다를 것입니다. "수정됨" 상태가 아니라 "병합 해제됨" 상태입니다. 그래서 우리는 다섯 번째 상태를 언급할 수 있었습니까? 나는 이것이 필요하다고 생각하지 않습니다. 보자:

자식 상태

우리는 이것이 특별하고 특이한 경우라고 스스로 확신할 수 있습니다. 계속하자:

자식 추가 *.txt

설명에서 "git commit"만 작성하도록 제안하는 것을 알 수 있습니다. 다음과 같이 작성해 보겠습니다.

자식 커밋

그렇게 해서 콘솔에서 충돌을 해결했습니다.

물론 이것은 통합 개발 환경에서 조금 더 쉽게 할 수 있습니다. 예를 들어 IntelliJ IDEA에서는 필요한 모든 작업을 바로 수행할 수 있도록 모든 것이 잘 설정되어 있습니다. 그러나 IDE는 "내부적으로" 많은 작업을 수행하며 정확히 무슨 일이 일어나고 있는지 이해하지 못하는 경우가 많습니다. 이해가 없으면 문제가 발생할 수 있습니다.

원격 저장소 작업

마지막 단계는 원격 저장소 작업에 필요한 몇 가지 추가 명령을 파악하는 것입니다.

내가 말했듯이 원격 저장소는 저장소가 저장되고 복제할 수 있는 장소입니다.

어떤 종류의 원격 저장소가 있습니까? 예:

  • GitHub는 리포지토리 및 공동 개발을 위한 최대 스토리지 플랫폼입니다.
  • GitLab은 오픈 소스를 사용하는 DevOps 수명 주기를 위한 웹 기반 도구입니다. 자체 위키, 버그 추적 시스템, CI/CD 파이프라인 및 기타 기능으로 코드 리포지토리를 관리하기 위한 Git 기반 시스템입니다.
  • BitBucket은 Mercurial 및 Git 버전 제어 시스템을 기반으로 하는 프로젝트 호스팅 및 공동 개발을 위한 웹 서비스입니다. 한때 무료 개인 리포지토리를 제공한다는 점에서 GitHub보다 큰 이점이 있었습니다. 작년에 GitHub는 이 기능을 모두에게 무료로 소개했습니다.
  • 등등…

원격 리포지토리로 작업할 때 가장 먼저 해야 할 일은 프로젝트를 로컬 리포지토리에 복제하는 것입니다.

이를 위해 로컬에서 만든 프로젝트를 내보냈습니다. 이제 누구나 다음과 같이 작성하여 직접 복제할 수 있습니다.

자식 클론 https://github.com/romankh3/git-demo

이제 프로젝트의 완전한 로컬 사본이 있습니다. 프로젝트의 로컬 복사본이 최신인지 확인하려면 다음을 작성하여 프로젝트를 가져와야 합니다.

힘내

우리의 경우 현재 원격 저장소의 아무 것도 변경되지 않았으므로 응답은 다음과 같습니다. 이미 최신입니다.

그러나 원격 리포지토리를 변경하면 로컬 리포지토리를 가져온 후 업데이트됩니다.

마지막으로 마지막 명령은 데이터를 원격 저장소로 푸시하는 것입니다. 로컬에서 수행한 작업을 원격 저장소로 보내려면 먼저 로컬에서 새 커밋을 생성해야 합니다. 이를 시연하기 위해 텍스트 파일에 다른 것을 추가해 보겠습니다.

이제 우리에게 꽤 흔한 일이 있습니다. 이 작업에 대한 커밋을 만듭니다.

자식 추가 test_resource.txt
git commit -m "푸시할 txt 준비"

이를 원격 저장소로 푸시하는 명령은 다음과 같습니다.

자식 푸시

지금은 그게 다야!

유용한 링크

2. IntelliJ IDEA에서 Git으로 작업하는 방법

이 파트에서는 ​​IntelliJ IDEA에서 Git으로 작업하는 방법을 배웁니다.

필수 입력:

  1. 읽고, 따라하고, 이전 부분을 이해하십시오. 이렇게 하면 모든 것이 설정되고 사용할 준비가 되었는지 확인하는 데 도움이 됩니다.
  2. IntelliJ IDEA를 설치합니다. 모든 것이 여기에 순서대로 있어야합니다 :)
  3. 완전한 숙달을 달성하기 위해 한 시간을 할당하십시오.

Git에 대한 기사에서 사용한 데모 프로젝트 로 작업해 봅시다 .

프로젝트를 로컬로 복제

여기에는 두 가지 옵션이 있습니다.

  1. 이미 GitHub 계정이 있고 나중에 무언가를 푸시하려는 경우 프로젝트를 포크하고 자신의 복사본을 복제하는 것이 좋습니다. 분기 작업 흐름의 예라는 제목 아래의 다른 문서에서 분기 생성 방법에 대해 읽을 수 있습니다 .
  2. 리포지토리를 복제하고 전체를 서버에 푸시하는 기능 없이 로컬에서 모든 작업을 수행합니다.

GitHub에서 프로젝트를 복제하려면 프로젝트 링크를 복사하여 IntelliJ IDEA에 전달해야 합니다.

  1. 프로젝트 주소 복사:

  2. IntelliJ IDEA를 열고 "버전 제어에서 가져오기"를 선택합니다.

  3. 프로젝트 주소를 복사하여 붙여넣기:

  4. IntelliJ IDEA 프로젝트를 생성하라는 메시지가 표시됩니다. 제안 수락:

  5. 빌드 시스템이 없으므로 "기존 소스에서 프로젝트 만들기"를 선택합니다.

  6. 다음으로 아름다운 화면을 볼 수 있습니다.

복제를 알아냈으니 이제 둘러볼 수 있습니다.

Git UI로서의 IntelliJ IDEA 첫인상

복제된 프로젝트를 자세히 살펴보십시오. 이미 버전 제어 시스템에 대한 많은 정보를 얻을 수 있습니다.

먼저 왼쪽 하단 모서리에 버전 제어 창이 있습니다. 여기에서 모든 로컬 변경 사항을 찾고 커밋 목록을 얻을 수 있습니다("git log"와 유사).

Log에 대한 토론으로 넘어 갑시다. 개발이 어떻게 진행되었는지 정확히 이해하는 데 도움이 되는 특정 시각화가 있습니다. 예를 들어 txt 커밋에 헤더가 추가된 새 분기가 생성된 다음 마스터 분기로 병합된 것을 볼 수 있습니다. 커밋을 클릭하면 오른쪽 모서리에서 커밋에 대한 모든 정보(모든 변경 사항 및 메타데이터)를 볼 수 있습니다.

또한 실제 변경 사항을 볼 수 있습니다. 또한 그곳에서 갈등이 해결되었음을 알 수 있습니다. IDEA는 이것을 아주 잘 보여줍니다.

이 커밋 중에 변경된 파일을 두 번 클릭하면 충돌이 어떻게 해결되었는지 확인할 수 있습니다.

왼쪽과 오른쪽에는 하나로 병합해야 하는 동일한 파일의 두 가지 버전이 있습니다. 그리고 중간에 최종 병합 결과가 있습니다.

프로젝트에 분기, 커밋 및 사용자가 많은 경우 분기, 사용자 및 날짜별로 별도로 검색해야 합니다.

시작하기 전에 우리가 속한 지점을 이해하는 방법을 설명하는 것도 좋습니다.

오른쪽 하단에 "Git: master"라는 버튼이 있습니다. "Git:" 뒤에 오는 것이 현재 브랜치입니다. 버튼을 클릭하면 다른 브랜치로 전환하고, 새 브랜치를 생성하고, 기존 브랜치의 이름을 바꾸는 등 많은 유용한 작업을 수행할 수 있습니다.

리포지토리 작업

유용한 단축키

향후 작업을 위해 몇 가지 매우 유용한 핫키를 기억해야 합니다.

  1. CTRL+T — 원격 저장소에서 최신 변경 사항을 가져옵니다(git pull).
  2. CTRL+K — 커밋을 생성하거나 현재 변경 사항을 모두 확인합니다. 여기에는 추적되지 않은 파일과 수정된 파일(git commit)이 모두 포함됩니다.
  3. CTRL+SHIFT+K — 변경 사항을 원격 저장소로 푸시하는 명령입니다. 로컬에서 생성되고 아직 원격 저장소에 없는 모든 커밋이 푸시됩니다(git push).
  4. ALT+CTRL+Z — 특정 파일의 변경 사항을 로컬 저장소에서 생성된 마지막 커밋 상태로 롤백합니다. 왼쪽 상단 모서리에서 전체 프로젝트를 선택하면 모든 파일의 변경 사항을 롤백할 수 있습니다.

우리는 무엇을 원합니까?

작업을 완료하려면 모든 곳에서 사용되는 기본 시나리오를 마스터해야 합니다.

목표는 별도의 브랜치에서 새 기능을 구현한 다음 원격 저장소로 푸시하는 것입니다(그런 다음 메인 브랜치에 대한 풀 요청도 생성해야 하지만 이 과정의 범위를 벗어납니다).

이를 위해 무엇이 필요합니까?

  1. 기본 분기(예: "마스터")의 모든 현재 변경 사항을 가져옵니다.

  2. 이 기본 분기에서 작업을 위한 별도의 분기를 만듭니다.

  3. 새로운 기능을 구현합니다.

  4. 메인 브랜치로 이동하여 작업하는 동안 새로운 변경 사항이 있는지 확인하십시오. 그렇지 않다면 모든 것이 정상입니다. 그러나 변경 사항이 있으면 다음을 수행합니다. 작업 브랜치로 이동하여 기본 브랜치에서 우리 브랜치로 변경 사항을 리베이스합니다 . 모든 것이 잘되면 훌륭합니다. 그러나 충돌이 있을 가능성은 전적으로 있습니다. 그럴 때 원격 저장소에서 시간을 낭비하지 않고 미리 해결할 수 있습니다.

    왜 이렇게 해야 하는지 궁금하시죠? 분기를 로컬 리포지토리로 푸시한 후 발생하는 충돌을 방지하는 좋은 매너입니다(물론 충돌이 계속 발생할 가능성은 있지만 훨씬 작아집니다 ) .

  5. 변경 사항을 원격 저장소로 푸시합니다.

원격 서버에서 변경 사항을 가져오는 방법은 무엇입니까?

새 커밋으로 README에 설명을 추가했으며 이러한 변경 사항을 적용하려고 합니다. 로컬 리포지토리와 원격 리포지토리 모두에서 변경된 경우 병합과 리베이스 중에서 선택하도록 초대됩니다. 우리는 병합을 선택합니다.

CTRL+T를 입력합니다 .

이제 README가 어떻게 변경되었는지, 즉 원격 저장소에서 가져온 변경 사항을 볼 수 있으며 오른쪽 아래 모서리에서 서버에서 온 변경 사항에 대한 모든 세부 정보를 볼 수 있습니다.

마스터를 기반으로 새 분기 만들기

여기에서는 모든 것이 간단합니다.

오른쪽 하단으로 이동하여 Git: master 를 클릭합니다 . + 새 분기를 선택합니다 .

Checkout branch 확인란을 선택된 상태로 두고 새 지점의 이름을 입력합니다. 우리의 경우: 이것은 readme-improver 입니다 .

Git: master 는 Git: readme-improver 로 변경됩니다 .

병렬 작업을 시뮬레이션해 봅시다

충돌이 나타나려면 누군가 충돌을 만들어야 합니다.

브라우저를 통해 새로운 커밋으로 README를 편집하여 병렬 작업을 시뮬레이션합니다. 마치 우리가 작업하는 동안 누군가가 동일한 파일을 변경한 것과 같습니다. 그 결과는 갈등이 될 것입니다. 10행에서 "fully"라는 단어를 제거하겠습니다.

기능 구현

우리의 임무는 README를 변경하고 새 기사에 설명을 추가하는 것입니다. 즉, Git에서의 작업은 IntelliJ IDEA를 거칩니다. 이거 추가 해봐:

변경이 완료되었습니다. 이제 커밋을 만들 수 있습니다. CTRL+K 를 누르면 다음이 제공됩니다.

커밋을 생성하기 전에 이 창에서 제공하는 내용을 자세히 살펴볼 필요가 있습니다.

커밋 메시지 섹션 에서 커밋과 관련된 텍스트를 작성합니다. 그런 다음 생성하려면 Commit 을 클릭해야 합니다 .

README가 변경되었다고 작성하고 커밋을 생성합니다. 커밋 이름과 함께 왼쪽 하단 모서리에 경고 팝업이 나타납니다.

메인 브랜치 변경 여부 확인

우리는 임무를 완수했습니다. 효과가있다. 우리는 테스트를 작성했습니다. 모든 것이 괜찮습니다. 하지만 서버에 푸시하기 전에 그 동안 메인 브랜치에 변경 사항이 있었는지 확인해야 합니다. 어떻게 그런 일이 일어날 수 있습니까? 아주 쉽게: 누군가 당신보다 작업을 나중에 받고 그 누군가는 당신이 작업을 완료하는 것보다 더 빨리 완료합니다.

따라서 마스터 브랜치로 이동해야 합니다. 이렇게 하려면 아래 스크린샷의 오른쪽 하단에 표시된 작업을 수행해야 합니다.

마스터 브랜치에서 CTRL+T를 눌러 원격 서버에서 최신 변경 사항을 가져옵니다. 변경 내용을 보면 무슨 일이 일어났는지 쉽게 알 수 있습니다.

"fully"라는 단어가 제거되었습니다. 마케팅 담당자가 그렇게 작성하면 안 된다고 판단하고 개발자에게 업데이트 작업을 부여했을 수도 있습니다.

이제 최신 버전의 마스터 브랜치에 대한 로컬 복사본이 생겼습니다. readme-improver 로 돌아가십시오 .

이제 마스터 브랜치에서 우리 브랜치로 변경 사항을 리베이스해야 합니다. 우리는 이렇게 합니다:

모든 작업을 올바르게 수행하고 저를 따라했다면 결과는 README 파일에 충돌이 표시되어야 합니다.

여기에는 이해하고 흡수해야 할 많은 정보가 있습니다. 여기에 충돌이 있는 파일 목록(이 경우 하나의 파일)이 표시됩니다. 세 가지 옵션 중에서 선택할 수 있습니다.

  1. accept yours — readme-improver의 변경 사항만 수락합니다.
  2. accept theirs — 마스터의 변경 사항만 수락합니다.
  3. 병합 — 보관할 항목과 버릴 항목을 직접 선택하세요.

무엇이 변경되었는지는 명확하지 않습니다. 마스터 브랜치에 변경 사항이 있는 경우 해당 브랜치에 변경 사항이 필요하므로 단순히 변경 사항을 수락할 수 없습니다. 따라서 병합을 선택합니다 .

여기서 우리는 세 부분이 있음을 알 수 있습니다.

  1. 이것은 readme-improver의 변경 사항입니다.
  2. 병합된 결과입니다. 현재로서는 변경 이전에 존재했던 것입니다.
  3. 마스터 브랜치의 변경 사항.

우리는 모두가 만족할 통합된 결과를 생성해야 합니다. 변경하기 전에 변경된 내용을 검토한 결과 단순히 "fully"라는 단어가 제거되었음을 알 수 있습니다. 그래, 문제 없어! 즉, 병합된 결과에서도 제거한 다음 변경 사항을 추가합니다. 병합된 결과를 수정하면 적용 을 클릭할 수 있습니다 .

그런 다음 알림이 팝업되어 리베이스가 성공했음을 알려줍니다.

거기! IntelliJ IDEA를 통해 첫 번째 충돌을 해결했습니다.

변경 사항을 원격 서버로 푸시

다음 단계는 변경 사항을 원격 서버에 푸시하고 풀 요청을 생성하는 것입니다. 이렇게 하려면 CTRL+SHIFT+K 를 누르기만 하면 됩니다 . 그런 다음 다음을 얻습니다.

왼쪽에는 원격 저장소로 푸시되지 않은 커밋 목록이 있습니다. 오른쪽에는 변경된 모든 파일이 있습니다. 그리고 그게 다야! 푸시를 누르시면 행복을 경험하실 수 있습니다 :)

푸시가 성공하면 오른쪽 하단에 다음과 같은 알림이 표시됩니다.

보너스: 풀 리퀘스트 생성

GitHub 리포지토리로 이동하면 GitHub가 우리가 원하는 것을 이미 알고 있음을 알 수 있습니다.

비교 및 풀 요청 을 클릭합니다 . 그런 다음 풀 요청 만들기 를 클릭합니다 . 우리는 미리 충돌을 해결했기 때문에 풀 요청을 생성할 때 즉시 병합할 수 있습니다.

지금은 그게 다야!