Переход от CVS к Git: $ Id: $ эквивалент? - PullRequest
119 голосов
/ 21 декабря 2008

Я прочитал кучу вопросов о простых инструментах контроля исходного кода, и Git показался мне разумным выбором. У меня есть и работает, и это работает хорошо до сих пор. Один аспект, который мне нравится в CVS, - это автоматическое увеличение номера версии.

Я понимаю, что это имеет меньше смысла в распределенном репозитории, но как разработчик мне нужно / нужно что-то вроде этого. Позвольте мне объяснить, почему:

Я использую Emacs. Периодически я просматриваю новые версии исходных файлов Lisp для сторонних пакетов. Скажем, у меня есть файл foo.el, который, согласно заголовку, версии 1.3; если я посмотрю последнюю версию и увижу, что она 1.143 или 2.6 или что-то еще, я знаю, что я довольно далеко позади.

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

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

Итак, какие у меня есть альтернативы? Если я не могу получить эквивалент $ Id: $, как еще я могу предоставить то, что я ищу?

Я должен упомянуть, что я ожидаю, что у конечного пользователя НЕ будет установлен Git, и даже если он этого не сделает, у него не будет локального репозитория (на самом деле, я ожидаю, что он не будет таким доступным).

Ответы [ 16 ]

65 голосов
/ 22 декабря 2008

SHA - это только одно представление версии (пусть и канонической). Команда git describe предлагает другие и делает это довольно хорошо.

Например, когда я запускаю git describe в моей основной ветке моего клиента memcached Java source, я получаю это:

2.2-16-gc0cd61a

Это говорит о двух важных вещах:

  1. Начиная с 2.2 * 1013 в этом дереве было ровно 16 коммитов
  2. Исходное дерево , точное , может отображаться на чьем-либо клоне.

Допустим, например, что вы упаковали файл version с источником (или даже переписали весь контент для распространения), чтобы показать это число. Допустим, что упакованная версия была 2.2-12-g6c4ae7a (не релиз, а действительная версия).

Теперь вы можете точно видеть, насколько далеко вы позади (4 коммитов), и вы можете точно видеть, какие 4 коммитов:

# The RHS of the .. can be origin/master or empty, or whatever you want.
% git log --pretty=format:"%h %an %s" 2.2-12-g6c4ae7a..2.2-16-gc0cd61a
c0cd61a Dustin Sallings More tries to get a timeout.
8c489ff Dustin Sallings Made the timeout test run on every protocol on every bui
fb326d5 Dustin Sallings Added a test for bug 35.
fba04e9 Valeri Felberg Support passing an expiration date into CAS operations.
51 голосов
/ 17 февраля 2011

К настоящему времени в Git есть поддержка $ Id: $. Чтобы включить его для файла README , вы должны поместить README идент в .gitattributes Подстановочные знаки в именах файлов поддерживаются. Подробнее см. man gitattributes .

31 голосов
/ 04 августа 2012

Это не необоснованный запрос от ОП.

Мой вариант использования:

  1. Я использую Git для своего личного кода, поэтому не сотрудничаю с другими.
  2. Я храню там системные скрипты Bash, которые могут перейти в /usr/local/bin, когда они будут готовы.

Я использую три отдельных компьютера с одним и тем же хранилищем Git. Было бы неплохо узнать, какая "версия" файла у меня есть в /usr/local/bin без необходимости выполнять руководство "diff -u <версия репозитория> <версия в /usr/local/bin>".

Для тех из вас, кто негативен, помните, что есть и другие варианты использования. Не все используют Git для совместной работы с файлами в репозитории Git, являющимися их «окончательным» местоположением.

В любом случае, я сделал так, чтобы создать файл атрибутов в хранилище следующим образом:

cat .git/info/attributes
# see man gitattributes
*.sh ident
*.pl ident
*.cgi ident

Затем поместите $ Id $ где-нибудь в файл (мне нравится ставить его после Шебанга).

Коммит. Обратите внимание, что это не делает расширение автоматически, как я ожидал. Вы должны повторно скопировать файл, например,

git commit foo.sh
rm foo.sh
git co foo.sh

И тогда вы увидите расширение, например:

$ head foo.sh
#!/bin/sh

# $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $

Некоторая полезная информация содержится в Как включить строку идентификатора для репозитория Git? .

23 голосов
/ 21 декабря 2008

Не уверен, что это когда-нибудь будет в Git. цитата Линуса :

"Само понятие подстановки ключевых слов просто идиотское. тривиально сделать "за пределами" реального отслеживания контента, если вы хотите имейте это при выполнении релизов в виде tar-шариков и т. д. "

Довольно просто проверить журнал - если вы отслеживаете стабильную ветку foo.el, вы можете увидеть, какие новые коммиты есть в журнале стабильной ветки, которых нет в вашей локальной копии. Если вы хотите смоделировать внутренний номер версии CVS, вы можете сравнить временную метку последнего коммита.

Редактировать: вы должны писать или использовать чужие скрипты, для этого, конечно, не делать это вручную.

20 голосов
/ 21 декабря 2008

Как я уже писал до :

Автоматически сгенерированные теги Id, которые показывают разумный номер версии, невозможно сделать с помощью инструментов DSCM, таких как Bazaar, потому что линия развития каждого может отличаться от всех других. Таким образом, кто-то может ссылаться на версию «1.41» файла, но ваша версия «1.41» этого файла отличается.

По сути, $ Id $ не имеет смысла для Bazaar, Git и других инструментов управления распределенным исходным кодом.

9 голосов
/ 13 ноября 2012

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

Я сделал это с помощью хита Git pre-commit и изменил свой скрипт, чтобы иметь возможность автоматически обновляться.

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

Мой в Ruby, но это не очень сложный код. Скрипт Ruby имеет:

MYVERSION = '1.090'
## Call script to do updateVersion from .git/hooks/pre-commit
def updateVersion
  # We add 1 because the next commit is probably one more - though this is a race
  commits = %x[git log #{$0} | grep '^commit ' | wc -l].to_i + 1
  vers = "1.%0.3d" % commits

  t = File.read($0)
  t.gsub!(/^MYVERSION = '(.*)'$/, "MYVERSION = '#{vers}'")
  bak = $0+'.bak'
  File.open(bak,'w') { |f| f.puts t }
  perm = File.stat($0).mode & 0xfff
  File.rename(bak,$0)
  File.chmod(perm,$0)
  exit
end

И затем у меня есть параметр командной строки (-updateVersion), который вызывает updateVersion для инструмента.

Наконец, я перехожу к главе Git и создаю исполняемый скрипт в .git/hooks/pre-commit.

Скрипт просто переходит в начало каталога Git и вызывает мой скрипт с помощью -updateVersion.

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

8 голосов
/ 21 декабря 2008

Если для вас важно иметь $ Keywords $, то, возможно, вы могли бы вместо этого попробовать Mercurial ? Он имеет расширение hgkeyword, которое реализует то, что вы хотите. В любом случае Mercurial интересен как DVCS.

8 голосов
/ 21 декабря 2008

Что-то, что делается с репозиториями Git, - это использование объекта tag. Это может быть использовано для маркировки коммита любой строкой и может использоваться для маркировки версий. Вы можете увидеть эти теги в репозитории с помощью команды git tag, которая возвращает все теги.

Тег легко проверить. Например, если есть тег v1.1, вы можете проверить этот тег на ветке следующим образом:

git checkout -b v1.1

Поскольку это объект верхнего уровня, вы увидите всю историю этого коммита, а также сможете запускать сравнения, вносить изменения и слияния.

Не только это, но тег сохраняется, даже если ветвь, на которой он находился, была удалена без слияния обратно в основную строку.

4 голосов
/ 21 декабря 2008

Если вы просто хотите, чтобы люди могли понять, насколько они устарели, Git может проинформировать их об этом несколькими довольно простыми способами. Например, они сравнивают даты последнего коммита на своем сундуке и вашем сундуке. Они могут использовать git cherry, чтобы увидеть, сколько коммитов произошло в вашем транке, которых нет в их транке.

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

Кроме того, я бы не стал распространять любезность на кого-либо, если вы не уверены, что он этого хочет. :)

3 голосов
/ 11 января 2017

Идентификаторы RCS хороши для однофайловых проектов, но для любого другого $ Id $ ничего не говорит о проекте (если вы не выполняете принудительную регистрацию в файле фиктивной версии).

Еще может быть интересно, как получить эквиваленты $ Author $, $ Date $, $ Revision $, $ RCSfile $ и т. Д. На уровне файла или на уровне фиксации (как разместить их там, где некоторые ключевые слова это другой вопрос). У меня нет ответа на эти вопросы, но я вижу необходимость их обновления, особенно когда файлы (теперь в Git) происходят из RCS-совместимых систем (CVS).

Такие ключевые слова могут быть интересны, если исходники распространяются отдельно от любого Git-репозитория (я тоже так делаю). Мое решение таково:

У каждого проекта есть свой собственный каталог, а в корне проекта у меня есть текстовый файл с именем .version, содержимое которого описывает текущую версию (имя, которое будет использоваться при экспорте исходных текстов).

При работе для следующего выпуска скрипт извлекает это .version число, некоторый дескриптор версии Git (например, git describe) и монотонный номер сборки в .build (плюс хост и дата) в автоматически сгенерированный исходный файл это связано с конечной программой, так что вы можете узнать, из какого источника и когда она была построена.

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

...