2016-06-30 6 views
1

두 개의 분기 developmaster이 있습니다. 아직 개발 된 커밋은 많지 만 master에는 없습니다. develop 브랜치를 정확히 master과 똑같이 보이게해야합니다. develop에 발생한 모든 변경 사항을 유지하기 위해 모든 변경 사항이 손실되지 않도록 develop에서 새 분기를 만듭니다.git - 브랜치를 마스터처럼 보이게하려면?

develop의 "복사"를 수행 한 후에는 안전하게 다시 설정하거나 master처럼 되돌릴 수 있습니까?

Git: reset/revert a whole branch to another branches state? 그래서 내가 할 수있는, 다시 설정하려면 :

나는이보고

git checkout develop 
git reset --hard master 

을 그러나 문제는 develop 지점이 이미 원격으로 밀려 이미 develop이 다른 사람을 뽑아 한 것입니다.

되돌리기 또는 다른 수단을 사용하여 더 안전하게 할 수 있습니까? 그러나 최신 커밋은 마스터 (핫픽스)에서 제공 되었기 때문에 develop에 보관해야하므로 모든 커밋을 수동으로 선택하는 것이 아니라 master 상태로 되돌릴 수있는 방법으로 되돌릴 수 있습니다 (가능한 경우).

commit hotfix2 - in both develop and master 
some other commits that are only in develop 
commit hotfix1 - in both develop and master 
some commits that are only in develop 
all commits that came when develop was created from master 
+0

그래서, 당신이하고 싶은 단지 개발에서 수행 된 모든 커밋을 취소한다 : 대신에 위의 그래서 우리는 단지 우리가 현재에 병합 ours 병합 전략을 사용하고 지점에서 아무것도를 폐기 할 수 있습니까? (예 : 내역에서 "일부 커밋"과 "다른 커밋"을 취소하십시오) – poke

+0

@poke 그렇습니다. 그러나 모든 커밋을 수행하고 실행 취소해야 할 항목을 선택하는 것보다 쉬운 방법이 있습니까? 이것은 단지 예제 일 뿐이며, 실제 실행에는 실행을 취소해야하는 커밋이 많으며 그 사이에 커밋이 있어야합니다. 'reset'을 사용하면 쉽습니다. 단지 브랜치를 지정할 수 있으며'master'처럼 보일 것입니다. – Andrius

답변

2

표준 프로세스는 비파괴 방법으로 커밋을 취소 할 git revert을 사용하는 것입니다

그래서 develop에 커밋의 역사는 (대부분의 최고 최신 날짜별로 커밋을 의미)이 같이 보입니다. 이 명령은 기본적으로 대상 확약의 역방향 diff를 취하여이를 적용하려고합니다. 따라서 모든 변경 사항을 취소하는 새로운 커밋을 얻습니다.

여러 커밋을 한 번에 실행 취소하려면 커밋 범위를 지정할 수도 있습니다. 실행 취소하려는 범위 (해당 핫픽스 사이의 범위)가 두 개인 경우에만 실제로 관리 할 수 ​​있습니다.

플래그 --no-commit 또는 -n으로 사용할 수 없으며은 자동으로 커밋을 만듭니다. 이렇게하면 복수 git revert -n <commit> 명령을 각각 다른 명령 뒤에 연결하여 커밋하지 않고 커밋 할 수 있습니다. 그런 다음 실행 취소하려는 모든 커밋 또는 커밋 범위를 모두 선택했으면 모든 커밋 또는 커밋 범위를 결합한 단일 커밋을 만들 수 있습니다.

develop 분기를 넣으려는 정확한 (작업 디렉토리) 상태의 다른 분기가 있으므로이 작업을 수행하는 것이 훨씬 쉽습니다. 당신이해야 할 일은 develop 브랜치에 master의 작업 트리를 체크 아웃하고 그 상태를 develop 브랜치에 위탁하는 것입니다. git checkout master -- .을 사용하면됩니다. 불행히도이 경로는 master 브랜치에 알려지지 않은 경로에서는 작동하지 않습니다. 따라서 develop 분기에 새 파일을 추가하면 해당 파일이 보관되므로 별도로 삭제해야합니다.

대신 master (정확히 동일한 내용을 가지고 있음)에서 새 분기를 시작하고 그 분기를 재설정하여 develop을 기반으로합니다. 그런 식으로 작업 디렉토리 상태를 master으로 유지하지만 커밋은 develop을 대신 수행합니다.이후, 우리는 빨리 감기 할 수 develop을 하나의 커밋이 :

# checkout a new branch off master 
git checkout -b new-develop master 

# make a soft reset to develop 
git reset --soft develop 

# commit the changes 
git commit 

# get back to develop and fast forward 
git checkout develop 
git merge --ff-only new-develop 
git branch -d new-develop 

이것은 당신이 develop에 단독으로있는 모든 커밋과 git revert -n 체인에 의해 얻을 것 같은 일이 발생합니다. 그 상태에 도달하는 몇 가지 다른 방법이 있지만 실제로는 가장 쉬운 방법입니다.

이 상태로 전환하는 방법에 관계없이 이후에 병합을 고려해야합니다. 병합은 실제로는 아무 것도하지 않지만 (두 가지가 같은 내용을 가지고 있기 때문에), 역사에서 가지를 결합하여 실제로 수렴하는 것을 볼 수 있습니다.

그래서 역사를 가정하는 것은 원래이 권리 같습니다

     master 
         ↓ 
* ------------ h1 ------ h2 
\    \   \ 
    * -- * -- * -- * -- * -- * 
          ↑ 
         develop 

당신이로 돌려 할 것 :

       master 
            ↓ 
* ------------ h1 ------ h2 ----- M 
\    \   \ /↖ 
    * -- * -- * -- * -- * -- * -- F develop 

F는 수정 우리가 위에서 만든 커밋되고. 이 경우 developmaster (git merge develop 켜고 master)에 병합하고 develop (git merge master 켜짐 develop)을 빨리 감아 해당 지점에서 개발 작업을 시작한다고 가정합니다. 물론, 선호한다면 다른 방향으로도 할 수 있습니다.

또는 M과 수정 F을 한 번에 병합 할 수도 있습니다. developmaster에 병합하고 master의 내용으로 모든 것을 병합합니다.

       master 
            ↓ 
* ------------ h1 ------ h2 ---- FM 
\    \   \ /↖ 
    * -- * -- * -- * -- * -- * ---/ develop 

당신은이 같은 손으로도 얻을 수 있습니다 :

# since we merge into master, we start there 
git checkout master 

# start the merge, but don’t attempt to fast-forward and do not 
# commit the merge automatically (since we want to change it) 
git merge --no-ff --no-commit develop 

# reset the index that was prepared during the merge 
git reset 

# now checkout the files from master and commit the merge 
git checkout master -- . 
git add . 
git commit 

을 그리고 실제로,이 git merge가 정확히이 일을 병합 전략을 함께 제공 등의 일반적인 시나리오는이 같을 것이다.

git checkout master 
git merge -s ours develop 
+0

흠, 이걸 시도했지만'개발 '을 취소하지 않은 것 같습니다. 'master'와'develop'에서 모두 변경된 파일 만 실행 취소합니다. 그러나 '개발'에만 추가되는 파일이 많지만 '마스터'는 아닙니다. 그리고 그것들은 유지됩니다. 그래서'development '를 체크 아웃하고 나서'master'로 병합하면 실제로 모든 파일을'master '에 추가합니다. 내가 여기서 뭔가를 놓치고 있니? 모든 파일을 수동으로 삭제하고 커밋해야합니까? – Andrius

+0

어떤 해결책을 시도 했습니까? 가장 마지막 것 ('ours' 병합 전략 사용)은 확실히 작동해야합니다; 다른 것들은'git checkout master - .' 전에'git reset'을해야 할 수도 있습니다 (잊었습니다). 병합 후에'git diff '는 아무 것도 반환하지 않고'git diff '는 더 이상 현재 브랜치에없는 많은 변경 사항을 보여 주어야합니다. – poke

+0

나는 첫번째 것을 시도했다 – Andrius