Обычно я использую Tortoise SVN, но я изучал Mercurial, поскольку это распределенная система контроля версий.
В обеих системах я ищу инструмент, который позволяет мне выбирать только части файла и фиксировать их. Если я хочу сделать это сейчас, мне нужно скопировать временную версию файла и сохранить только те изменения, которые я хочу зафиксировать в текущей версии, а затем снова скопировать временную версию в текущую версию после фиксации. Это такая неприятность, и программа должна сделать это за меня.
Я слышал, что Git поддерживает это, дайте мне знать, правильно ли это.
Патчи @PavelRadzivilovsky приветствуются. Я имею в виду, что вы можете написать патч и отправить его в список рассылки dev @.
Теперь для этой цели есть встроенная утилита фиксации interactive
, которая поставляется прямо из коробки с Mercurial. Смотрите мой ответ ниже.
Mercurial может сделать это с помощью расширения записывать.
Вам будет предложено указать каждый файл и каждый фрагмент различий. Например:
% hg record
diff --git a/prelim.tex b/prelim.tex
2 hunks, 4 lines changed
examine changes to 'prelim.tex'? [Ynsfdaq?]
@@ -12,7 +12,7 @@
\setmonofont[Scale=0.88]{Consolas}
% missing from xunicode.sty
\DeclareUTFcomposite[\UTFencname]{x00ED}{\'}{\i}
-\else
+\else foo
\usepackage[pdftex]{graphicx}
\fi
record this change to 'prelim.tex'? [Ynsfdaq?]
@@ -1281,3 +1281,5 @@
%% Local variables:
%% mode: latex
%% End:
+
+foo
\ No newline at end of file
record this change to 'prelim.tex'? [Ynsfdaq?] n
Waiting for Emacs...
После коммита оставшиеся различия останутся позади:
% hg di
diff --git a/prelim.tex b/prelim.tex
--- a/prelim.tex
+++ b/prelim.tex
@@ -1281,3 +1281,5 @@
%% Local variables:
%% mode: latex
%% End:
+
+foo
\ No newline at end of file
В качестве альтернативы вам может быть проще использовать MQ (Mercurial Queues) для разделения отдельных изменений в вашем репозитории на исправления. Также существует вариант записи MQ (qrecord).
Обновлять: Также попробуйте расширение Crecord, которое предоставляет интерфейс curses для выбора фрагментов / строк.
Жаль, что для этого нет графического интерфейса. Замечательно делать это с GitX.
Аминь. GitX - это причина то, по которой я использую Git; желаю, чтобы Мурчаль был так же способен (К сожалению, я слишком перегружен проектами с открытым исходным кодом, чтобы исправить это, хотя я внес свой вклад как в GitX, так и в Murky :-)
Для этого есть инструмент с графическим интерфейсом: Tortoisehg поддерживает выбор фрагментов.
… И теперь, используя TortoiseHg, ему не хватает возможности откатить кусок, который предоставляет GitX, и в целом предоставляет гораздо менее полезный интерфейс. Возможность легко удалять непреднамеренные (например, только пробелы) изменения из diff очень важна ...
Расширению Record также не хватает возможности редактировать блок перед его фиксацией. Очень полезная функция, без которой сложно жить, ИМХО.
Отсутствие возможности редактировать кусок - это хорошо. Я не поклонник «функций», которые позволяют моим разработчикам фиксировать код, который они на самом деле не создали или не тестировали. К моменту запуска hg record
отдельные блоки должен будут рассматриваться как неизменяемые; если они нуждаются в дальнейшем редактировании, то пора прервать фиксацию.
Я бы рекомендовал не работать так.
Если у вас есть наборы изменений, установите A, который готов к регистрации, и установите B, который еще не готов, как вы можете быть уверены, что только проверка набора A не нарушит вашу сборку / тесты? Вы можете пропустить некоторые строки, забыть о строках в другом файле или не осознавать зависимость, которую A имеет от B, нарушая сборку для других.
Ваши коммиты должны быть незаметными атомарными изменениями, которые не нарушают сборку для вас или другие в вашей команде. Если вы частично фиксируете файл, вы значительно увеличиваете вероятность того, что вы сломаете сборку для других, не зная об этом, пока к вам не постучится какой-нибудь несчастный коллега.
Большой вопрос в том, почему вы чувствуете необходимость работать таким образом?
Git позволяет это, группируя смежные строки вместе. Это может быть ДЕЙСТВИТЕЛЬНО удобно, если вам нужно проверить что-то простое и не хотите делать ветку.
Обычно это происходит потому, что я пишу слишком много кода перед фиксацией. Я могу изменить две разные вещи в файле и хочу зафиксировать их с разными комментариями.
Git поддерживает (с git stash --keep-index) изоляцию только тех изменений, которые вы собираетесь зафиксировать, что позволяет вам легко запускать модульные тесты или что-то еще.
Хороший совет для кодовых обезьян, но мы, более сообразительные, можем справиться с объединением различий и их фиксацией по частям.
Из соглашений разработчиков VisionMap: «Нет кошмара рецензента хуже, чем сочетание одного опасного изменения с тысячей тривиальных. В этом смысле значимое изменение должно быть тщательно очищено от любого непонятного мусора»
См. Сообщение Райана Томайко (создателя GitHub) об этом: tomayko.com/writings/the-thing-about-git
Случай, с которым я всегда сталкиваюсь, когда хочу иметь возможность сделать это, находится в файлах .csproj. Поскольку каждый файл, включенный в проект C#, включен в файл .csproj, если я хочу сделать фиксацию, которая добавляет NewFile1.cs, а НЕ NewFile2.cs, тогда я должен разделить файл .csproj на 2 коммита.
@ rally25rs - Давно не рассматривал этот вопрос, но я с вами согласен. Думаю, я всегда объяснял это недостатком самодисциплины или чем-то подобным, когда сталкивался с этими «крайними случаями», но, взглянув на это снова, я вижу, насколько это было бы действительно полезно.
Это проблема для Subversion, потому что фиксация затрагивает всех, но для распределенных систем, таких как Git и Mercurial, это вообще не проблема. Вы можете разделить свои коммиты и протестировать их каждый, прежде чем распространять свои изменения. Если вы действительно 1337, вы даже можете потом отредактировать историю, чтобы убрать все ошибки, чтобы никому больше не нужно было знать, что они произошли. Как уже упоминалось, это все еще можно сделать в Subversion, если человек, который это делает, достаточно компетентен. Централизованная модель гарантирует, что в репозиториях Subversion что-то неизбежно сломается.
Это не всегда выбор. Иногда бывает поздно, и вы откладываете изменение до другого дня, увлекаетесь другой функцией / изменением, прежде чем осознаете, что произошло. Мы люди. Наша VCS должна справиться с нашей неуклюжей работой. Это произойдет, даже если по ошибке. Поэтому обязательно наличие такой функции. tomayko.com/writings/the-thing-about-git
@craigb Один, очень распространенный вариант использования, - это изменение строки конфигурации в файле (сервер, на который он указывает, или включение регистрации отладки), и вы не хотите, чтобы эта строка была в репо. Мне также нравится переносить все мои изменения форматирования из изменений, которые действительно что-то делают. Как заметил кто-то другой, нет ничего хуже, чем попытаться найти что-то в патче, заваленном несущественными изменениями. Да, вы правы, что вы не должны отправлять код, пока не запустите то, что находится в HEAD вашего репо.
Я не согласен с тем, что коммиты на основе блоков мешают атомарности. Часто они действительно помогают этой причине, например: измененная рабочая копия, которая включает что-то, не имеющее отношения к фиксации. Собирание фиксации фактически поощряет атомарность, удерживая нерелевантные изменения в фиксации.
Я спросил аналогичный вопрос совсем недавно, и получившийся ответ об использовании расширение hgshelve был именно тем, что я искал.
Перед тем, как сделать коммит, вы можете поместить изменения из разных файлов (или фрагменты изменений в файле) на «полку», а затем зафиксировать то, что вы хотите. Затем вы можете отложить изменения, которые не фиксировали, и продолжить работу.
Пользуюсь им последние несколько дней, и он мне очень нравится. Очень легко визуализировать и использовать.
Да, git позволяет это делать. У команды git add
есть опция -p
(или --patch
), которая позволяет вам просматривать ваши изменения по частям, выбирать, какие из них выполнять (вы также можете уточнить фрагменты или отредактировать исправления на месте). Вы также можете использовать интерактивный режим для git-add (git add -i
) и использовать параметр «p».
Вот скринкаст по интерактивному добавлению, который также демонстрирует возможность исправления git add
.
Также обратите внимание, что git gui
предлагает графический способ сделать это.
Обратите внимание на TortoiseHG, который будет выполнять выбор фрагментов и позволяет вам фиксировать разные изменения в одном файле и в разных фиксациях.
Это даже позволит вам зафиксировать все изменения в некоторых файлах вместе с частичными изменениями в других файлах за одну фиксацию.
http://tortoisehg.bitbucket.io/
графический интерфейс только для Windows
@ user7610 нет, он также поддерживает Linux
расширение Nautilus и CLI да, но некоторые инструменты графического интерфейса в TortoiseHg предназначены для Windows
@ user7610 "некоторые инструменты графического интерфейса"! = "графический интерфейс"
Mercurial теперь предоставляет опцию --interactive
(или -i
) для команды commit
, которая сразу включает эту функцию.
Это работает непосредственно из командной строки, так что это идеально, если вы энтузиаст командной строки!
Бег
> hg commit -i
запускает интерактивный сеанс, который позволяет изучать, редактировать и записывать отдельные изменения для создания фиксации.
Это очень похоже на параметры --patch
и --interactive
для команд git add
и git commit
.
Это лучший ответ. Нет необходимости в расширении и т. д. Спасибо за ответ.
Разработать такой инструмент для SVN должно быть довольно легко. Интересно, почему этого еще никто не сделал?