it-roy-ru.com

Переход от CVS к Git: $ Id: $ эквивалент?

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

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

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

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

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

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

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

115
Joe Casadonte

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

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

2.2-16-gc0cd61a

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

  1. В этом дереве было ровно 16 коммитов с 2.2
  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.
64
Dustin

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

51
Sebastian Pipping

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

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

  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?.

31
Imran-UK

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

«Само понятие подстановки ключевых слов просто идиотское. Это просто Тривиально делать« за пределами »реального отслеживания контента, если вы хотите Иметь его, когда делаете деревья релизов в виде tar-шариков и т.д.»

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

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

23
orip

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

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

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

20
Bombe

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

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

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

Мой в 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 обновляется в зависимости от количества коммитов.

9
David Ljung Madison

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

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

git checkout -b v1.1

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

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

8
Abizern

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

8
Keltia

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

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

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

4
skiphoppy

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

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

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

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

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

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

3
U. Windl

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

Сначала получите изменения в удаленном Origin, но не объединяйте их в ветку master:

% git fetch

Затем получите журнал изменений, которые произошли в данном файле между вашей веткой master и удаленным Origin/master.

% git log master..Origin/master foo.el

Это дает вам сообщения журнала всех коммитов, которые произошли в удаленном хранилище с момента вашего последнего слияния Origin/master с вашим master.

Если вы просто хотите подсчитать изменения, передайте его wc. Скажи так:

% git rev-list master..Origin/master foo.el | wc -l
3
Otto

Я согласен с теми, кто думает, что замена токенов относится не к инструментам контроля версий, а к инструментам сборки.

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

1
Agustí Sánchez

Поскольку вы используете Emacs, вам может повезти :)

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

0
Amr Mostafa

Чтобы применить расширение ко всем файлам во всех подкаталогах в хранилище, добавьте файл .gitattributes в каталог верхнего уровня в хранилище (т. Е. Куда вы обычно помещаете файл .gitignore), содержащий:

* ident

Чтобы убедиться в этом, вам нужно сначала выполнить эффективную проверку файлов, например, удалить или отредактировать их любым способом. Затем восстановите их с помощью:

git checkout .

И вы должны увидеть, что $Id$ заменен чем-то вроде:

$Id: ea701b0bb744c90c620f315e2438bc6b764cdb87 $

От man gitattributes:

идент

Когда для пути задан идентификатор атрибута, Git заменяет $ Id $ на объект blob с $ Id:, за которым следует шестнадцатеричный объект blob с 40 символами имя, сопровождаемое знаком доллара $ при оформлении заказа. Любая последовательность байтов, которая начинается с $ Id: и заканчивается на $ в файле рабочего дерева и заменяется на $ Id $ при регистрации.

Этот идентификатор будет меняться каждый раз, когда фиксируется новая версия файла.

0
Nagev

Я также пришел из SCCS, RCS и CVS (%W% %G% %U%).

У меня была похожая проблема. Я хотел знать, какая версия кода была в любой системе, в которой он работает. Система может быть или не быть подключена к любой сети. Система может иметь или не иметь установленный Git. В системе может быть установлен или не установлен репозиторий GitHub.

Я хотел одно и то же решение для нескольких типов кода (.sh, .go, .yml, .xml и т.д.). Я хотел, чтобы любой человек без знания Git или GitHub мог ответить на вопрос «Какую версию вы используете?»

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

https://github.com/BradleyA/markit

git clone https://github.com/BradleyA/markit
cd markit
0
Bradley Allen