source

기트풀은 어떤 경우에 해로울 수 있습니까?

nicesource 2023. 5. 29. 10:59
반응형

기트풀은 어떤 경우에 해로울 수 있습니까?

에 제 동 한 있 명 는 데 그 는 이 료 중 에 ▁that 그 는 ▁i ▁who 제 데 있 ▁claims 는 ▁colleague료 이git pull해롭고, 누군가가 그것을 사용할 때마다 화가 납니다.

git pull명령은 로컬 리포지토리를 업데이트하는 표준 방법인 것 같습니다.사용하시겠습니까?git pull문제를 만들까요?어떤 문제가 발생합니까?깃 저장소를 업데이트하는 더 좋은 방법이 있습니까?

요약

기적으로본,git pull코드 기록에 노이즈와 복잡성을 추가하는 병합 커밋을 만듭니다. 외에 게가다.pull에서는 변경사항이 들어오는 변경사항의 영향을 받을 수 있는 방법을 쉽게 고려하지 않습니다.

git pull명령은 빠른 전달 병합만 수행하는 한 안전합니다.한다면git pull빠른 전달 병합만 수행하도록 구성되어 있으며, 빠른 전달 병합이 불가능할 경우 Git가 종료되고 오류가 발생합니다.이를 통해 들어오는 커밋을 살펴보고, 커밋이 로컬 커밋에 어떤 영향을 미칠지 생각해 보고, 최적의 조치(합병, 기본 재배치, 재설정 등)를 결정할 수 있습니다.

Git 2.0 이상 버전에서는 다음을 실행할 수 있습니다.

git config --global pull.ff only

기본 동작을 빨리 감기로만 변경합니다.Git 버전이 1.6.6과 1.9.x 사이인 경우 다음과 같이 입력하는 습관을 들여야 합니다.

git pull --ff-only

의 모든 대해서는 Git의 나러모버전다음구권것다장니합을성할든그을서에의를 하는 것을 합니다.git up다음과 같은 별칭:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

및사용을 사용합니다.git upgit pull는 이 가명이 더다니좋습이보다 더 좋습니다.git pull --ff-only이유:

  • 모든 (고대가 아닌) Git 버전에서 작동합니다.
  • (현재 작업 중인 분기뿐만 아니라) 모든 업스트림 분기를 가져옵니다.
  • 그것은 오래된 것을 씻어냅니다.origin/*더 이상 상류에 존재하지 않는 가지

git pull

git pull제대로 사용하면 나쁘지 않습니다.최근 Git에 대한 몇 가지 변경 사항으로 인해 사용이 더 쉬워졌습니다.git pull적절하게, 하지만 불행하게도 평원의 기본 행동.git pull에는 몇 문제가 .

  • 그것은 역사에 불필요한 비선형성을 도입합니다.
  • 의도적으로 상향 조정된 커밋을 실수로 다시 쉽게 재도입할 수 있습니다.
  • 예측할 수 없는 방식으로 작업 디렉토리를 수정합니다.
  • 이 하는 일을 것은 일입니다.git pull
  • 원격 분기에 대한 정확한 기반 재설정이 어렵습니다.
  • 원격 저장소에서 삭제된 분기는 정리되지 않습니다.

이러한 문제에 대해서는 아래에서 자세히 설명합니다.

비선형 이력

적으로기본,,git pull는 명은실동다니를 실행하는 것과 .git fetch에 뒤에git merge @{u} 않은 과 같이 병합 합니다.git pull병합 커밋을 만듭니다.

병합 커밋은 본질적으로 나쁜 것은 아니지만 위험할 수 있으므로 다음과 같이 취급해야 합니다.

  • 병합 커밋은 본질적으로 검사하기 어렵습니다.병합이 무엇을 하는지 이해하려면 모든 부모의 차이점을 이해해야 합니다.전통적인 차이는 이 다차원 정보를 잘 전달하지 못합니다.이와 대조적으로, 일련의 일반적인 커밋은 검토하기 쉽습니다.
  • 병합 충돌 해결은 까다롭고 병합 커밋을 검토하기 어렵기 때문에 실수가 오랫동안 감지되지 않는 경우가 많습니다.
  • 병합은 정기적인 커밋의 효과를 조용히 대체할 수 있습니다.코드는 더 이상 증분 커밋의 합계가 아니며, 실제로 변경된 것에 대한 오해로 이어집니다.
  • 병합 커밋은 일부 연속 통합 체계를 중단시킬 수 있습니다(예: 두 번째 부모가 진행 중인 불완전한 작업을 가리키는 가정된 규칙에 따라 첫 번째 부모 경로만 자동 구축).

물론 병합을 위한 시간과 장소가 있지만 병합을 사용해야 하는 시기와 사용해서는 안 되는 시기를 이해하면 저장소의 유용성을 향상시킬 수 있습니다.

Git의 목적은 코드베이스의 진화를 쉽게 공유하고 소비하기 위한 것이지, 전개된 대로 정확하게 기록하기 위한 것이 아닙니다.(반대하는 경우 다음 사항을 고려합니다.rebase명령 및 명령이 생성된 이유).의 병생커에서 입니다.git pull다른 사용자에게 유용한 의미론을 전달하지 않습니다. 사용자가 변경을 완료하기 전에 다른 사용자가 리포지토리에 푸시했다고만 말합니다.다른 사람들에게 의미가 없고 위험할 수 있는 병합 커밋이 있는 이유는 무엇입니까?

를 구성할 수 .git pull병합 대신 기본값을 다시 지정하지만 문제도 있습니다(나중에 추가).대신,git pull빨리 감기 병합만 수행하도록 구성해야 합니다.

재조정된 커밋의 재도입

누군가가 나뭇가지를 다시 기초하고 힘으로 밀었다고 가정해 보겠습니다.일반적으로 이런 일이 발생하면 안 되지만, 실수로 커밋되어 푸시된 50Gb 로그 파일을 제거해야 하는 경우도 있습니다.에 의해 .git pull새 버전의 업스트림 분기를 로컬 리포지토리에 있는 이전 버전으로 병합합니다.만약 여러분이 결과를 밀고 나간다면, 피치 포크와 횃불이 여러분의 길로 오기 시작할 것입니다.

일부 사람들은 진짜 문제가 강제 업데이트라고 주장할 수 있습니다.네, 일반적으로 가능한 한 힘을 주지 않는 것이 바람직하지만, 어쩔 수 없는 경우도 있습니다.개발자는 포스 업데이트를 처리할 준비가 되어 있어야 합니다. 포스 업데이트는 때때로 발생하기 때문입니다.이는 일반을 통해 이전 커밋에서 맹목적으로 병합하지 않음을 의미합니다.git pull.

깜짝 작업 디렉터리 수정

작업 디렉터리 또는 인덱스의 모양을 예측할 수 있는 방법은 없습니다.git pull완료되었습니다.다른 작업을 수행하기 전에 해결해야 할 병합 충돌이 있을 수 있습니다. 다른 사용자가 실수로 50GiB 로그 파일을 밀어 넣었기 때문에 작업 디렉터리에 50GiB 로그 파일이 추가되거나 작업 중인 디렉터리의 이름이 변경될 수 있습니다.

git remote update -p(또는)git fetch --all -p병합 또는 기본 재배치를 결정하기 전에 다른 사용자의 커밋을 확인할 수 있으므로 작업을 수행하기 전에 계획을 구성할 수 있습니다.

다른 사용자의 커밋을 검토하는 어려움

현재 변경 작업을 진행 중이며 다른 사용자가 방금 푸시한 커밋을 검토하기를 원한다고 가정합니다. git pull의 병합(또는 기본 재배치) 작업은 작업 디렉터리와 인덱스를 수정합니다. 즉, 작업 디렉터리와 인덱스가 깨끗해야 합니다.

사용할 수 있습니다.git stash그리고 나서.git pull복습을 마치면 어떻게 하죠?원래 위치로 돌아가려면 생성된 병합을 취소해야 합니다.git pull그리고 스택을 적용합니다.

git remote update -p(또는)git fetch --all -p작업 디렉터리 또는 인덱스는 수정되지 않으므로, 준비 및/또는 준비되지 않은 변경 사항이 있더라도 언제든지 실행해도 안전합니다.작업 중인 커밋을 보관하거나 완료할 걱정 없이 현재 작업을 일시 중지하고 다른 사용자의 커밋을 검토할 수 있습니다. git pull그런 유연성을 제공하지 않습니다.

원격 분기 기반 재배치

일반적인 Git 사용 패턴은 다음을 수행하는 것입니다.git pull최신 변경 사항에 이어 다음과 같은 변경 사항을 가져오다git rebase @{u}합병 커밋을 제거하기 위해.git pull소개했다.Git에는 다음과 같이 두 단계를 한 단계로 줄일 수 있는 몇 가지 구성 옵션이 있습니다.git pull병합 대신 기본 재배치를 수행합니다( 참조).branch.<branch>.rebase,branch.autosetuprebase,그리고.pull.rebase옵션)을 선택합니다.

안타깝게도 유지하려는 푸시되지 않은 병합 커밋이 있는 경우(예: 푸시된 피쳐 분기를 다음으로 병합하는 커밋)master), 어느 것도 기본값을 변경하지 않습니다(git pull와 함께branch.<branch>.rebase로 설정한.true) 또는 병합 명령(기본값)git pull동작) 다음에 기본 재배치가 작동합니다.그 이유는git rebase다음과 같은 기능 없이 병합(DAG를 선형화함)을 제거합니다)--preserve-merges선택.병합을 유지하도록 기본 재배치 작업을 구성할 수 없으며 병합 풀 다음에 다음과 같은 작업을 수행합니다.git rebase -p @{u}병합-제거로 인해 발생한 병합을 제거하지 못합니다.업데이트:Git v1.8.5 추가git pull --rebase=preserve그리고.git config pull.rebase preserve이러한 원인git pull하기 위해서git rebase --preserve-merges업스트림 커밋을 가져온 후.(알려주신 펑크스터님께 감사드립니다!

삭제된 분기 정리

git pull원격 리포지토리에서 삭제된 분기에 해당하는 원격 추적 분기를 잘라내지 않습니다.예를 들어, 다른 사용자가 분기를 삭제한 경우foo원격 레포에서, 당신은 여전히 볼 수 있을 것입니다.origin/foo.

이로 인해 사용자는 죽은 가지가 여전히 활성 상태라고 생각하여 실수로 부활하게 됩니다.

더 나은 대안:사용하다git up대신에git pull

대신에git pull다음을 만들어 사용하는 것이 좋습니다.git up별칭:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

이 별칭은 모든 업스트림 분기에서 모든 최신 커밋을 다운로드하고(dead branch 제거) 로컬 브랜치를 업스트림 브랜치의 최신 커밋으로 빠르게 전달하려고 합니다.성공하면 로컬 커밋이 없으므로 병합 충돌 위험이 없습니다.로컬(푸시되지 않은) 커밋이 있는 경우 빠른 전달이 실패하여 작업을 수행하기 전에 업스트림 커밋을 검토할 수 있습니다.

이렇게 하면 로컬 변경사항이 없는 경우에만 작업 디렉토리가 예측할 수 없는 방식으로 수정됩니다.와는 달리git pull,git up병합 충돌을 해결할 것이라는 메시지가 표시되지 않습니다.

다른 옵션:git pull --ff-only --all -p

다음은 위의 대안입니다.git up별칭:

git config --global alias.up 'pull --ff-only --all -p'

이 버전의git up이전과 동일한 동작을 합니다.git up별칭, 예외:

  • 로컬 분기가 업스트림 분기로 구성되지 않은 경우 오류 메시지가 조금 더 암호화됩니다.
  • 그것은 문서화되지 않은 특징에 의존합니다.-p에 전달되는 논쟁fetch) 향후 Git 버전에서 변경될 수 있음

Git 2.0 이상을 실행 중인 경우

Git 2.0 이상 버전을 사용하여 구성할 수 있습니다.git pull기본적으로 빨리 감기 병합만 수행하려면:

git config --global pull.ff only

이것이 원인입니다.git pull처럼 행동함git pull --ff-only그러나 여전히 모든 업스트림 커밋을 가져오거나 오래된 것을 정리하지는 않습니다.origin/*나뭇가지들을 여전히 선호합니다.git up.

HackerNews에서 발생한 토론에서 얻은 제 대답은 다음과 같습니다.

저는 베터리지의 헤드라인 법칙을 사용하여 질문에 대답하고 싶습니다.이유는git pull유해하다고 간주됩니까?절대 아닙니다.

  • 비선형성이 본질적으로 나쁜 것은 아닙니다.만약 그들이 실제 역사를 나타낸다면 그들은 괜찮습니다.
  • 업스트림에 기반을 둔 커밋을 실수로 다시 도입한 것은 업스트림에 기록을 잘못 쓴 결과입니다.기록이 여러 리포지토리를 따라 복제되면 기록을 다시 쓸 수 없습니다.
  • 작업 디렉토리를 수정하는 것은 예상되는 결과입니다. 즉, hg/monotone/darcs/other_dvcs_predating_git의 동작에 직면하여 논쟁의 여지가 있는 유용성의 결과이지만, 본질적으로 나쁘지는 않습니다.
  • 병합을 위해 다른 사람의 작업을 검토하기 위해 일시 중지해야 하며, git pull에서 예상되는 동작입니다.병합하지 않으려면 gitfetch를 사용해야 합니다.다시 말하지만, 이것은 이전의 인기 있는 dvcs와 비교했을 때 git의 특이성이지만, 예상되는 동작이며 본질적으로 나쁘지 않습니다.
  • 원격 지점을 기준으로 리베이스하기 어렵게 만드는 것이 좋습니다.꼭 필요한 경우가 아니면 역사를 다시 쓰지 마세요.저는 아무리 해도 (가짜) 선형 역사를 추구하는 것을 이해할 수 없습니다.
  • 가지를 치우지 않는 것은 좋습니다.각 레포는 무엇을 보유하고 싶은지 알고 있습니다.Git는 마스터-노예 관계에 대한 개념이 없습니다.

Git를 올바르게 사용하면 유해하다고 생각되지 않습니다.사용 사례를 보면 부정적인 영향을 받지만 공유 내역을 수정하지 않는 것만으로 문제를 피할 수 있습니다.

승인된 답변은 주장합니다.

병합을 유지하도록 기본 재배치 작업을 구성할 수 없습니다.

하지만 그 답변을 게시하는 Git 1.8.5에서, 당신은 할 수 있습니다.

git pull --rebase=preserve

또는

git config --global pull.rebase preserve

또는

git config branch.<name>.rebase preserve

서류상으로는

언제preserve,또한 패스--preserve-merges로컬로 커밋된 병합 커밋이 'git pull'을 실행하여 평평해지지 않도록 'git rebase'와 함께 표시됩니다.

이 이전 토론에서는 git pull --rebase --reserve-merges라는 더 자세한 정보와 다이어그램을 제공합니다.그것은 또한 이유를 설명합니다.git pull --rebase=preserve는 와동하않습다니지일않다▁the▁▁same와 하지 않습니다.git pull --rebase --preserve-merges옳은 일을 하는 것이 아닙니다.

이전의 다른 토론에서는 리베이스의 보존 병합 변형이 실제로 무엇을 하는지, 그리고 일반 리베이스보다 훨씬 더 복잡한 방법을 설명합니다.git의 "rebase --reserve-merges"가 정확히 무엇을 하는 것입니까 (그리고 그 이유는 무엇입니까?)

이전 git 저장소에 가면 그들이 제안하는 별칭이 다릅니다.https://github.com/aanand/git-up

git config --global alias.up 'pull --rebase --autostash'

이것은 저에게 딱 맞습니다.

언급URL : https://stackoverflow.com/questions/15316601/in-what-cases-could-git-pull-be-harmful

반응형