Как я могу переместить коммиты из ствола в ветку в Git? - PullRequest
16 голосов
/ 04 марта 2010

Я сделал кучу коммитов мастеру и понял после того, что они должны были быть в ветке.

Я смотрел на различные вещи о перебазировании, слиянии и сбросе мастера. Но никакие попытки манипуляции не привели к истории, которая выглядит так, как я пытаюсь сделать.

Мои попытки привели меня к мысли, что для перемещения мастера во времени требуется некоторая комбинация rebase --onto и reset --hard. Но мое понимание ветвления Git оставляет желать лучшего. Часть этого - узнать, как я могу это использовать.

Следует отметить, что ни одно из изменений, которые я пытаюсь перенести, не было отменено.

Ток

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo

Желаемый результат

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo

Ответы [ 3 ]

9 голосов
/ 04 марта 2010

Вариант ответа Мартина, который не обязательно будет применим к вашей ситуации, но я все равно хочу опубликовать его:)

Предположим, вы забыли создать ветку при коммите o, поэтому у вас есть:

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]

И тогда вы поняли, что действительно хотели:

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic

В этом случае вы можете создать ветку на o, используя ее хеш:

git branch topic # creates new branch 'topic' - will be at commit `f`
git checkout o -b newmaster # creates new branch called newmaster pointing on commit `o` (please replace `o` with the actual hash)
git branch -M newmaster master # force rename newmaster to master (means master points on hash `o`)

Вы будете в основной ветке (commit o), поэтому в качестве последнего шага вы можете:

git checkout topic

Хеш, конечно, может быть только первыми 5 символами.

EDIT

Не имеет большого значения, что вы используете git-svn, что действительно важно, так это то, что вы не опубликовали свою основную ветку в любой момент после o

Ветка в git - это всего лишь указатель на коммит. Вот почему ветвление так дешево: вы просто создаете указатель, и у вас есть ветвь.

Я не знаю, как отслеживать удаленные ветви, но вам может понадобиться настроить это после переименования / перемещения ваших ветвей.

6 голосов
/ 04 марта 2010

Я не уверен, что переименование ветвей - правильное решение, так как оно поможет вам:

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo

до:

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk

(при условии, что вы переименовываете remote/foo, что не рекомендуется: сначала вы должны отследить, а затем переименовать, но даже если конечный результат отличается от того, что вам нужно)

, который не является желаемым «желаемым результатом» (foo должен начинаться с F, а не с M):

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo

Этого можно достичь только через rebase --onto

git checkout --track -b origin/foo  # create a local branch named after the remote one
git branch tmp                      # mark current foo HEAD to 'F'
git branch -f foo master            # put foo where it should b: at 'f'
git branch -f master tmp^           # reset master to M, parent of tmp
git checkout tmp                    # go to where we must replay the commits
git rebase --onto tmp master foo    # replay a to f on top of tmp
git svn dcommit                     # push the local foo in order to update remote/foo

давая вам:

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo
1 голос
/ 01 декабря 2011

Почти правильно, что предлагает hasen j, но мне пришлось сделать несколько небольших модификаций (и я использую git-svn):

# create the branch with your commits
git branch performance
# fork the master to a new branch at the commit before your local, non pushed commits
git branch newmaster 2d0516dfe8252de87
# checkout your branch 
git checkout performance
# rename the newmaster
git branch -M newmaster master
# now checkout the master
git checkout master

Вы не можете переименовать ветку, в которой вы находитесь, поэтому я проверил ветку производительности, куда я переместил свои коммиты.

...