Зафиксировать файл в другую ветку без проверки - PullRequest
30 голосов
/ 28 октября 2011

Можно ли зафиксировать файл в ветке git без проверки этой ветки?Если да, то как?

По сути, я хочу иметь возможность сохранять файл в моей ветке страниц github, не переключая ветки все время.Есть мысли?

Обновление: Невозможно сделать то, что я хочу (см. Комментарии ниже для варианта использования).В итоге я программно клонировал мой текущий каталог в каталог tmp, затем проверил мою ветку в этом каталоге tmp (не влияет на мой рабочий каталог) и зафиксировал мои файлы в клоне каталога tmp.Когда я закончу, я возвращаюсь в свой рабочий каталог и удаляю каталог tmp.Отстой, но это единственный способ зафиксировать файлы в другой ветке без изменения текущей рабочей ветки рабочего каталога.Если у кого-то есть лучшее решение, пожалуйста, добавьте его ниже.Если это лучше, чем «это невозможно сделать», я приму ваше.

Ответы [ 9 ]

17 голосов
/ 28 октября 2011

Это невозможно.

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

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

Что касается вашего конкретного варианта использования, простой способ - сохранить две копии вашей работы: одну извлеченную в master ветви, а другую в pages ветви.

В рабочую копию pages добавьте копию master в качестве удаленного репо.

  • Вы фиксируете страницы на master
  • Извлечение из master на pages copy
  • push на GitHub
  • сбросить ветку master в своем предыдущем состоянии.
12 голосов
/ 16 февраля 2012

Это можно сделать, переопределив git commit.

Это можно сделать с помощью различных вызовов git hash-object

Но этого трудно достичь.

Пожалуйста, прочитайте progit глава 9 для более подробной информации и полного примера того, как имитировать коммит.

10 голосов
/ 30 октября 2011

Пока в вашем текущем индексе нет ничего, что отличалось бы от HEAD, которое вы хотите сохранить, вы можете сделать что-то вроде этого.(Если вы хотите сохранить свой индекс, вы можете временно экспортировать переменную среды GIT_INDEX_FILE, чтобы указать на временный файл для выполнения этих команд.)

# Reset index and HEAD to otherbranch
git reset otherbranch

# make commit for otherbranch
git add file-to-commit
git commit "edited file"

# force recreate otherbranch to here
git branch -f otherbranch

# Go back to where we were before
# (two commits ago, the reset and the commit)
git reset HEAD@{2}

На самом деле мы никогда не извлекали otherbranch и наши файлы рабочего дерева не были затронуты.

9 голосов
/ 13 декабря 2016

Как уже говорили несколько других, это буквально возможно, но нецелесообразно.

Однако, начиная с Git 2.5 (с некоторыми важными исправлениями в 2.6 и незначительными исправлениями с тех пор), - это практичный способ сделать это, используя git worktree add.

Допустим, например, что вы хотите работать с ветками main и doc "одновременно" или с ветвями develop и test "одновременно", но две ветви под вопросом намеренно содержатся разные вещи. (Например, ветвь doc имеет документацию, которая существует вне или рядом с кодом, или ветвь test имеет тесты, которые будут выполняться с кодом, но не распределены, или в которых ожидаются сбои, для которых эти тесты умышленно пропущено на стороне develop, или как угодно.)

Вместо просто:

git clone -b develop <source> theclone

с последующей работой в theclone с постоянным переключением между двумя ветвями, вы должны:

git clone -b develop <source> theclone

но потом:

cd theclone
git worktree add ../ct test  # check out branch test in ../ct

или просто:

git worktree add ../test     # check out branch test in ../test

Теперь вы можете запускать свои тесты в ../test при разработке в theclone. Вы можете объединять и / или перебазировать изменения из одной ветви в другую обычным способом: базовый репозиторий уже является общим, поэтому git push или git fetch не требуется. Вы просто отметили обе ветви в двух отдельных рабочих деревьях с именами theclone и test от верхнего уровня.

3 голосов
/ 07 ноября 2013

Не могу согласиться, это невозможно. Это возможно при смешивании git stash push, git stash pop, git checkout, git checkout, git add и git commit.

Как я понимаю проблему:

Вы находитесь на главном филиале и внесли некоторые изменения в файл patched.txt, и вы хотели бы зафиксировать этот файл в другой ветви.

То, что вы хотели бы сделать, это:

  • сохранить все изменения в этом репо, выполнив git stash
  • оформить заказ file.txt из спрятанной стопки
  • добавить файл patched (и только этот файл) в новую ветку
  • вернуться в состояние репо до модификации file.txt

Этого можно достичь, выполнив следующие команды:

destBranch=patch
thisBranch=master
FileToPutToOtherBranch="file1.txt file2.txt 'file with space in name.txt'"
message="patched files $FileToPutToOtherBranch"
                                                                                  #assumption: we are on master to which modifications to file.txt should not belong
git stash &&\                                                                     #at this point we have clean repository to $thisBranch
git checkout -b $destBranch &&\           
git checkout stash@{0} -- $FileToPutToOtherBranch &&                              #if there are many files, repeat this step                                         #create branch if does not exist (param -b)
git add $FileToPutToOtherBranch &&\                                               # at this point this is equal to git add . --update
git commit -m "$message" &&\
git checkout $thisBranch &&\
git stash apply &&\                                                               # or pop if want to loose backup
git checkout $thisBranch -- $FileToPutToOtherBranch                               # get unpatched files from previous branch

Причина, по которой я использую «&&», и в конце концов, если кто-то скопирует и вставит этот фрагмент в терминал, даже если произойдет одна ошибка, будут выполнены следующие команды, что не очень хорошо. \ для информирования оболочки о том, что команда продолжается в следующей строке.

Чтобы доказать это, я предоставляю среду тестирования для этого фрагмента

mkdir -p /tmp/gitcommitToAnyBranch && cd /tmp/gitcommitToAnyBranch &&\
git init 
echo 'this is master file' > file1.txt
echo 'this is file we do not want to have modified in patch branch because it does not     patches any feature' > docs.txt
git add file1.txt && git commit -m "initial commit" 
echo 'now this file gets patched' > file1.txt
git status

Теперь, если вы запустите мой скрипт с параметрами

destBranch=patch
thisBranch=`git rev-parse --abbrev-ref HEAD`
FileToPutToOtherBranch="file1.txt"
message="patched file $FileToPutToOtherBranch"

У вас будет file1.txt изменено только в ветке патча, подробнее см. gitk --all

3 голосов
/ 28 октября 2011

Хотя в настоящее время нет единой команды для этого, есть как минимум две другие опции.

  1. Вы можете использовать github api для создания коммита. В этой публикации подробно описано создание коммита в репозитории github.

  2. Создание страниц github в виде подмодуля .

  3. Используйте серию сантехнических команд для создания коммита.
    В git book есть описание сантехнических команд, используемых для создания коммита

примечание: команда теперь mktree, а не mk-tree

2 голосов
/ 14 января 2017

Я сделал маленький инструмент, который делает именно это: https://github.com/qwertzguy/git-quick

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

За кулисами используется комбинация git worktree и sparse checkout. Источник довольно маленький, поэтому вы можете прочитать его.

1 голос
/ 12 апреля 2012

Если вы случайно изменили вещи в неправильной ветке, вот несколько простых шагов:

  1. Передайте эти изменения;
  2. Объедините их в правильную ветку;
  3. Извлеките ветку, в которой вы были сначала, и сбросьте ее до коммита до;
  4. Очистите ваши изменения с помощью "git checkout -.".

После этого все должно быть в порядке.Вы также можете выборочно объединять, сбрасывать и очищать ваши модификации.

0 голосов
/ 29 марта 2014

Вот как я это делаю:

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

git reset --soft 'HEAD^'

добавить файлы, которые вы хотите добавить

git add .

создать новую временную ветку:

git checkout -b oops-temp

зафиксируйте ваши изменения:

git commit -m "message about this commit"

Оформите ветку, которую вы хотели проверить:

git checkout realbranch

объединить старую ветку:

git merge oops-temp

удалить старую ветку:

git branch -D oops-temp
...