Переход от 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 ]

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

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

Сначала получите изменения в удаленном источнике, но не объединяйте их с вашей 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
1 голос
/ 17 августа 2018

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

* ident

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

git checkout .

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

$Id: ea701b0bb744c90c620f315e2438bc6b764cdb87 $

С man gitattributes:

идент

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

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

1 голос
/ 11 августа 2016

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

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

0 голосов
/ 11 июня 2019

Если вы хотите, чтобы информация о коммите git доступна в вашем коде, то у вас есть , чтобы сделать шаг перед сборкой, чтобы получить его там. В bash для C / C ++ это может выглядеть примерно так:

prebuild.sh

#!/bin/bash
commit=$(git rev-parse HEAD)
tag=$(git describe --tags --always ${commit})
cat <<EOF >version.c
#include "version.h"
const char* git_tag="${tag}";
const char* git_commit="${commit}";
EOF

с version.h выглядит как:

#pragma once
const char* git_tag;
const char* git_commit;

Тогда, где вам это нужно, в вашем коде #include "version.h" и ссылках git_tag или git_commit при необходимости.

А у вашего Makefile может быть что-то вроде этого:

all: package
version:
  ./prebuild.sh
package: version
  # the normal build stuff for your project

Это имеет преимущество:

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

Эта реализация prepublish.sh имеет недостатки:

  • принудительная перекомпиляция, даже если git_tag / git_commit не изменился.
  • он не учитывает локальные измененные файлы, которые не были зафиксированы, но влияет на сборку.
    • используйте git describe --tags --always --dirty, чтобы поймать этот вариант использования.
  • загрязняет глобальное пространство имен.

Любитель prebuild.sh, который мог бы избежать этих проблем, оставлен читателю в качестве упражнения.

0 голосов
/ 13 февраля 2018

Я также пришел из 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 голосов
/ 26 апреля 2009

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

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

...