Git Pull Force – Git으로 로컬 변경 사항을 덮어 쓰는 방법

코딩을 배우면 조만간 버전 제어 시스템에 대해서도 배우게됩니다. 이 분야에는 경쟁 도구가 많지만 그중 하나는 업계의 거의 모든 사람들이 사용하는 사실상의 표준입니다. 브랜드에 그 이름을 사용하는 회사가있을 정도로 인기가 높습니다. 물론 Git에 대해 이야기하고 있습니다.

Git은 강력한 도구이지만 그 힘은 잘 숨겨져 있습니다. Git에 능숙 해지려면 이해해야 할 몇 가지 필수 개념이 있습니다. 좋은 소식은 일단 배우면 탈출 할 수없는 문제에 거의 부딪히지 않는다는 것입니다.

일반적인 워크 플로우

일반적인 Git 워크 플로에서는 로컬 저장소, 원격 저장소 및 하나 이상의 분기를 사용합니다. 리포지토리는 전체 기록 및 모든 분기를 포함하여 프로젝트에 대한 모든 정보를 저장합니다. 브랜치는 기본적으로 빈 프로젝트에서 현재 상태로 이어지는 변경 사항 모음입니다.

리포지토리를 복제 한 후 로컬 복사본에서 작업하고 새로운 변경 사항을 도입합니다. 로컬 변경 사항을 원격 저장소에 푸시 할 때까지 모든 작업은 컴퓨터에서만 사용할 수 있습니다.

작업을 완료하면 원격 저장소와 동기화 할 시간입니다. 프로젝트의 진행 상황을 따라 잡기 위해 원격 변경 사항을 가져오고, 다른 사용자와 작업을 공유하기 위해 로컬 변경 사항을 푸시하려고합니다.

로컬 변경

여러분과 나머지 팀원이 완전히 별개의 파일을 작업 할 때 모든 것이 잘됩니다. 무슨 일이 있어도 서로의 발을 밟지 않을 것입니다.

그러나 당신과 당신의 팀원이 같은 장소에서 동시에 변경 사항을 도입하는 경우가 있습니다. 그리고 그것은 일반적으로 문제가 시작되는 곳입니다.

git pull무서운 사람을보기 위해 처형 한 적이 error: Your local changes to the following files would be overwritten by merge:있습니까? 조만간 모든 사람들이 그 문제에 직면합니다.

여기서 더 혼란스러운 것은 아무것도 병합하고 싶지 않다는 것입니다. 실제로 당기는 것은 생각했던 것보다 조금 더 복잡합니다.

Git Pull은 얼마나 정확하게 작동합니까?

당기기는 단일 작업이 아닙니다. 원격 서버에서 데이터를 가져온 다음 변경 사항을 로컬 저장소와 병합하는 것으로 구성됩니다. 다음 두 작업은 원하는 경우 수동으로 수행 할 수 있습니다.

git fetch git merge origin/$CURRENT_BRANCH

origin/$CURRENT_BRANCH부분의 의미 :

  • Git은 이름이 지정된 원격 저장소 origin(복제 한 저장소)의 변경 사항을 병합합니다.
  • 추가 된 $CURRENT_BRANCH
  • 로컬 체크 아웃 지점에 아직없는

Git은 커밋되지 않은 변경 사항이 없을 때만 병합을 수행하기 때문에 커밋되지 않은 변경 사항을 실행할 때마다 git pull문제가 발생할 수 있습니다. 다행히도 한 조각으로 문제에서 벗어날 수있는 방법이 있습니다!

우리는 가족

다양한 접근 방식

커밋되지 않은 로컬 변경 사항이 있고 여전히 원격 서버에서 새 버전을 가져 오려는 경우 사용 사례는 일반적으로 다음 시나리오 중 하나에 해당합니다. 어느 한 쪽:

  • 로컬 변경 사항에 신경 쓰지 않고 덮어 쓰고 싶을 때
  • 변경 사항에 대해 매우 신경을 쓰고 원격 변경 후에 적용하고 싶습니다.
  • 원격 수정을 다운로드하고 싶지만 아직 적용하지 않으려는 경우

각 접근 방식에는 다른 솔루션이 필요합니다.

당신은 로컬 변화에 대해 신경 쓰지 않는다

이 경우 커밋되지 않은 모든 로컬 변경 사항을 삭제하려고합니다. 실험을 위해 파일을 수정했지만 더 이상 수정할 필요가 없습니다. 관심있는 것은 업스트림을 최신 상태로 유지하는 것입니다.

즉, 원격 변경 사항을 가져오고 병합하는 사이에 한 단계를 더 추가해야합니다. 이 단계는 분기를 수정되지 않은 상태로 재설정하여 git merge작업 을 허용 합니다.

git fetch git reset --hard HEAD git merge origin/$CURRENT_BRANCH

이 명령을 실행할 때마다 브랜치 이름을 입력하고 싶지 않다면 Git에는 업스트림 브랜치를 가리키는 멋진 바로 가기가 @{u}있습니다. 업스트림 분기는 사용자가 푸시하고 가져 오는 원격 저장소의 분기입니다.

바로 가기를 사용하면 위의 명령이 다음과 같이 표시됩니다.

git fetch git reset --hard HEAD git merge '@{u}'

쉘이 그것을 해석하지 못하도록 예제에서 단축키를 인용하고 있습니다.

당신은 지역적 변화에 매우 신경을 쓴다

커밋되지 않은 변경 사항이 중요한 경우 두 가지 옵션이 있습니다. 커밋 한 다음을 수행 git pull하거나 숨길 수 있습니다.

숨김은 나중에 다시 가져올 수 있도록 변경 사항을 잠시 보관하는 것을 의미합니다. 더 정확하게 말하면 git stash현재 브랜치에는 표시되지 않지만 Git에서 여전히 액세스 할 수있는 커밋을 만듭니다.

마지막 숨김에 저장된 변경 사항을 다시 가져 오려면 git stash pop명령 을 사용합니다 . 숨김 된 변경 사항을 성공적으로 적용한 후이 명령은 더 이상 필요하지 않으므로 숨김 커미트도 제거합니다.

그러면 워크 플로는 다음과 같습니다.

git fetch git stash git merge '@{u}' git stash pop

By default, the changes from the stash will become staged. If you want to unstage them, use the command git restore --staged (if using Git newer than 2.25.0).

You Just Want to Download the Remote Changes

The last scenario is a little different from the previous ones. Let's say that you are in the middle of a very messy refactoring. Neither losing the changes nor stashing them is an option. Yet, you still want to have the remote changes available to run git diff against them.

As you have probably figured out, downloading the remote changes does not require git pull at all! git fetch is just enough.

One thing to note is that by default, git fetch will only bring you changes from the current branch. To get all the changes from all the branches, use git fetch --all. And if you'd like to clean up some of the branches that no longer exist in the remote repository, git fetch --all --prune will do the cleaning up!

Some Automation

Have you heard of Git Config? It's a file where Git stores all of the user-configured settings. It resides in your home directory: either as ~/.gitconfig or ~/.config/git/config. You can edit it to add some custom aliases that will be understood as Git commands.

For example, to have a shortcut equivalent to git diff --cached (that shows the difference between the current branch and the staged files), you'd add the following section:

[alias] dc = diff --cached

After that, you can run git dc whenever you wish to review the changes. Going this way, we can set up a few aliases related to the previous use cases.

[alias] pull_force = !"git fetch --all; git reset --hard HEAD; git merge @{u}" pf = pull_force pull_stash = !"git fetch --all; git stash; git merge @{u}; git stash pop"

This way, running git pull_force will overwrite the local changes, while git pull_stash will preserve them.

The Other Git Pull Force

Curious minds may have already discovered that there is such a thing as git pull --force. However, this is a very different beast to what's presented in this article.

It may sound like something that would help us overwrite local changes. Instead, it lets us fetch the changes from one remote branch to a different local branch. git pull --force only modifies the behavior of the fetching part. It is therefore equivalent to git fetch --force.

Like git push, git fetch allows us to specify which local and remote branch do we want to operate on. git fetch origin/feature-1:my-feature will mean that the changes in the feature-1 branch from the remote repository will end up visible on the local branch my-feature. When such an operation modifies the existing history, it is not permitted by Git without an explicit --force parameter.

Just like git push --force allows overwriting remote branches, git fetch --force (or git pull --force) allows overwriting local branches. It is always used with source and destination branches mentioned as parameters. An alternative approach to overwriting local changes using git --pull force could be git pull --force "@{u}:HEAD".

Conclusion

Git의 세계는 광대합니다. 이 기사에서는 리포지토리 유지 관리의 측면 중 하나 인 원격 변경 사항을 로컬 리포지토리에 통합하기 만했습니다. 이 일상적인 시나리오조차도이 버전 관리 도구의 내부 메커니즘을 좀 더 자세히 살펴 봐야했습니다.

실제 사용 사례를 학습하면 내부에서 Git이 작동하는 방식을 더 잘 이해할 수 있습니다. 이것은 당신이 어려움에 처할 때마다 당신이 힘을 얻도록 만들 것입니다. 우리 모두는 때때로 그렇게합니다.