it-swarm.com.ru

как вы толкаете только некоторые из ваших локальных коммитов git?

Предположим, у меня есть 5 локальных коммитов. Я хочу перенести только 2 из них в централизованное хранилище (используя рабочий процесс в стиле SVN). Как мне это сделать?

Это не сработало:

git checkout HEAD~3  #set head to three commits ago
git Push #attempt Push from that head

Это заканчивает тем, что выдвигало все 5 локальных коммитов.

Я полагаю, что я мог бы сделать git reset, чтобы фактически отменить мои коммиты, затем git stash, а затем git Push - но у меня уже есть записанные сообщения коммитов и организованные файлы, и я не хочу повторять их.

Я чувствую, что какой-то флаг, переданный в Push или сброс, будет работать.

Если это поможет, вот мой конфиг

[ramanujan:~/myrepo/.git]$cat config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "Origin"]
        url = ssh://server/git/myrepo.git
        fetch = +refs/heads/*:refs/remotes/Origin/*
[branch "master"]
        remote = Origin
        merge = refs/heads/master
134
ramanujan

Предполагая, что ваши коммиты находятся в главной ветви, и вы хотите перенести их в удаленную главную ветку:

$ git Push Origin master~3:master

Если вы использовали git-svn:

$ git svn dcommit master~3

В случае с git-svn вы также можете использовать HEAD ~ 3, так как он ожидает фиксации. В случае прямого git вам нужно использовать имя ветки, потому что HEAD не правильно оценивается в refspec.

Вы также можете использовать более длительный подход:

$ git checkout -b tocommit HEAD~3
$ git Push Origin tocommit:master

Если вы привыкли к такому типу рабочих процессов, вам следует рассмотреть возможность выполнения своей работы в отдельной ветке. Тогда вы можете сделать что-то вроде:

$ git checkout master
$ git merge working~3
$ git Push Origin master:master

Обратите внимание, что часть "Origin master: master", вероятно, не является обязательной для вашей настройки.

170
Ryan Graham

Что я делаю, так это работаю в местном отделении под названием "работа". Эта ветвь содержит все временные коммиты (такие как временные решения или опции частной сборки или что-то еще), которые я не собираюсь отправлять в обратный репозиторий. Я работаю над этой веткой, затем, когда я хочу сделать коммит, я переключаюсь на основную ветвь и выбираю нужные коммиты, которые я хочу зафиксировать , затем толкни мастер.

После извлечения изменений из апстрима в мою основную ветку я git checkout work и git rebase master. Это переписывает все мои локальные изменения, чтобы быть в конце истории.

Я на самом деле использую git svn с этим рабочим процессом, поэтому моя операция "Push" включает git svn dcommit. Я также использую tig , которая является средством просмотра репозитория графического интерфейса в текстовом режиме Nice, для выбора подходящих коммитов.

16
Greg Hewgill

По умолчанию git-Push выдвигает все ветви. Когда вы делаете это:

 git checkout HEAD~3  #set head to three commits ago
 git Push #attempt Push from that head

Вы переходите к отдельному HEAD (вы не находитесь ни в одной ветви), а затем проталкиваете все ветви, включая локальный мастер (который все еще там, где он был), к удаленному мастеру.

Ручное решение:

 git Push Origin HEAD:master

Если вы обнаружите, что поведение по умолчанию для всех веток сбивает с толку (и опасно!), Добавьте это в ваш ~/.gitconfig:

 [remote.Origin]
    Push = HEAD

Тогда толкается только та ветка, на которой вы находитесь. В вашем примере (отдельная голова) вы бы получили это сообщение об ошибке, а не случайно нажали неправильные коммиты:

 error: unable to Push to unqualified destination: HEAD
13
Thomas Leonard

Короткий ответ:

git Push <latest commit SHA1 until you want commits to be pushed>

Примеры:

git Push fc47b2

git Push HEAD~2

Длинный ответ:

Коммиты связаны друг с другом в виде цепочки с родительским/дочерним механизмом. Таким образом, отправка коммита на самом деле также толкает все родительские коммиты к этому коммиту, который неизвестен удаленному. Это неявно делается, когда вы git Push текущий коммит: все предыдущие коммиты также передаются, потому что эта команда эквивалентна git Push HEAD.

Таким образом, вопрос может быть переписан в Как протолкнуть конкретный коммит и этот конкретный коммит может быть, например, HEAD ~ 2.

Если коммиты, которые вы хотите нажать, не являются последовательными, просто измените их порядок с помощью git rebase -i перед конкретным Push.

6
Tim

1) Используйте "git rebase", чтобы изменить порядок ваших коммитов, если хотите.

git rebase -i

Эта команда отобразит что-то вроде этого в вашем редакторе (я использую vim)

pick 4791291 commitA
pick a2bdfbd commitB
pick c3d4961 commitC
pick aa1cefc commitD
pick 9781434 commitE

# Rebase ..............
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using Shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out




^G Get Help         ^O WriteOut         ^R Read File        ^Y Prev Page                ^K Cut Text         ^C Cur Pos
^X Exit             ^J Justify          ^W Where Is         ^V Next Page            ^U UnCut Text       ^T To Spell

2) Упорядочить ваши коммиты по вашему выбору с помощью простой резки пасты. Предположим, новый заказ

выбрать 9781434 коммит

выбрать c3d4961 commitC

выбрать 4791291 commitA

выберите aa1cefc commitD

выбрать a2bdfbd commitB

Сделайте эти изменения в вашем редакторе и нажмите Ctrl + O (writeOut)

Или вы также можете использовать

git rebase -i HEAD~<commitNumber>

Вы можете проверить новую последовательность с

git log

3) Теперь используйте

git Push <remoteName> <commit SHA>:<remoteBranchName>

Если только одна ветка на удаленной (Origin) и одна на локальной (master), просто используйте

git Push <commit SHA>
git Push aa1cefc

Это будет Push commitB и commitD.

4
shiva