2010-08-15 4 views
251

Как я могу клонировать репозиторий с конкретной ревизии, то, как я обычно делаю в Mercurial:Как клонировать репозиторий git с помощью конкретной ревизии/набора изменений?

hg clone -r 3 /path/to/repository 
+2

не специфичен для изменения наборов или изменений, но клонировать последнюю в конкретной отрасли может быть столь же эффективным, т.е. 'мерзавцем клон -b 10.1 https://github.com/MariaDB/server.git --depth = 1 mariadb-server-src' – MrMesees

+0

Возможный дубликат [Загрузить конкретный тег с Git] (http://stackoverflow.com/questions/ 791959/download-a-specific-tag-with-git) – SlightlyCuban

+0

Хотите ли вы, чтобы история была неглубокой, т. Е. Содержала только версию 3 в вашем примере или ее родители? – sschuberth

ответ

126

UPDATE для GIT версии> 1.7 Использование мерзавец клонов и сброса мерзавец, как описано в ответ Vaibhav Баджпаи в

Если вы не хотите получать полный репозиторий, то вы, вероятно, не следует использовать clone. Вы всегда можете просто использовать выборку, чтобы выбрать ветку, которую хотите извлечь. Я не специалист по hg, поэтому я не знаю подробностей -r, но в git вы можете сделать что-то вроде этого.

# make a new blank repository in the current directory 
git init 

# add a remote 
git remote add origin url://to/source/repository 

# fetch a commit (or branch or tag) of interest 
# Note: the full history of this commit will be retrieved 
git fetch origin <sha1-of-commit-of-interest> 

# reset this repository's master branch to the commit of interest 
git reset --hard FETCH_HEAD 
+27

Я не думаю, что 'git fetch origin ' works; похоже, вам нужно передать именованную ссылку, такую ​​как имя тега или ветки. См. Http://kerneltrap.org/mailarchive/git/2009/1/13/4707444 – artur

+38

@artur: Вы не думаете, что это работает, или вы его пробовали, и это не работает? –

+3

Работал хорошо для меня ....... просто говорю. –

42

Клонирование репозиторий, метко, клоны весь репозиторий: нет способа выбрать только одну ревизию клонировать. Однако, как только вы выполните git clone, вы можете проверить конкретную ревизию, выполнив checkout <rev>.

+3

Я не хочу клонировать только одну ревизию. Я просто хочу указать предел клонирования. Другими словами, я хочу клонировать все до указанной ревизии. – John

+4

Вы не можете этого сделать. 'git clone' захватывает весь репозиторий. После этого вы можете проверить конкретную ревизию. – 2010-08-15 20:54:03

+3

Другими словами, Джон, это не то, как работает Гит. – Amber

26

Если вы имеете в виду вы хотите получать все от начала до определенной точки, ответ Чарльз Бейли является совершенным. Если вы хотите сделать обратное и получить подмножество истории, возвращающейся с текущей даты, вы можете использовать git clone --depth [N], где N - количество оборотов истории, которые вы хотите. Однако:

--depth

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

+3

Более новая версия git улучшила мелкие клоны, и вы можете тянуть и отталкивать ее. – orion78fr

23

Просто подвести вещи (. GIT V 1.7.2.1):

  1. делать регулярные git clone где вы хотите репо (получает все на сегодняшний день - я знаю, не то, что хотел , мы получаем там)
  2. git checkout <sha1 rev> в оборот вы хотите
  3. git reset --hard
  4. git checkout -b master
+9

Жалуется, что мастер уже существует на шаге 4 – a1an

+6

Что делают шаги 3 и 4? – BrainSlugs83

+0

Шаг 4 не работал для меня, но до шага 3 сделал трюк - Спасибо – gnB

576
$ git clone $URL 
$ cd $PROJECT_NAME 
$ git reset --hard $SHA1 

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

$ git pull 
+0

git clone https://github.com/respository/path –

+22

** Идеальное решение **. Легче использовать и запоминать, чем все остальные. Это должен быть принятый ответ. – trejder

+0

Согласен. Гораздо быстрее, чем принятый. – Avio

-1

вы можете использовать просто git checkout <commit hash>

в этой последовательности

bash git clone [URLTORepository] git checkout [commithash]

совершить хэш выглядит следующим образом «45ef55ac20ce2389c 9180658fdba35f4a663d204 "

+0

зачем вам 'git init' здесь? –

+0

в случае, если вы начинаете с пустой папки без инициализации git .. –

+0

клон инициализирует папку для вас –

17

TL; DR - просто создайте тег в исходном репозитории против фиксации, которую вы хотите клонировать, и используйте тег в команде fetch.Вы можете удалить тег из исходного репо позже, чтобы очистить.

Ну, его 2014 год, и похоже, что принятый ответ Чарльза Бейли с 2010 года хорошо и действительно устарел, и большинство (всех?) Других ответов связаны с клонированием, которое многие люди надеются избежать.

Следующее решение обеспечивает то, что ищет OP и многие другие, что является способом создания копии репозитория, включая историю, но только до определенной фиксации.

Вот команды, которые я использовал с мерзавца версии 2.1.2 клонировать локальный репозиторий (т.е. хранилище в другой директории.) До определенного момента:

# in the source repository, create a tag against the commit you want to check out 
git tag -m "Temporary tag" tmptag <sha1> 

# create a new directory and change into that directory 
cd somewhere_else;mkdir newdir;cd newdir 

# ...and create a new repository 
git init 

# add the source repository as a remote (this can be a URL or a directory) 
git remote add origin /path/to/original/repo 

# fetch the tag, which will include the entire repo and history up to that point 
git fetch origin refs/tags/tmptag 

# reset the head of the repository 
git reset --hard FETCH_HEAD 

# you can now change back to the original repository and remove the temporary tag 
cd original_repo 
git tag -d tmptag 

Надеемся, что это решение продолжает работать для еще несколько лет! :-)

-5
git clone -o <sha1-of-the-commit> <repository-url> <local-dir-name> 

git использует слово origin в смену широко известной revision

Ниже приводится отрывок из ручного $ git help clone

--origin <name>, -o <name> 
    Instead of using the remote name origin to keep track of the upstream repository, use <name>. 
+2

Не знаю, почему вы получаете вниз, это было именно то, что я надеялся увидеть для моего варианта использования: получение конкретной версии ядра Linux из версии, которую они не имели в своем силе, как релиз (кажется, проблема с людьми RPi), без загружая всю историю с несколькими гигабайтами Linux. Кстати, это сработало. – Fordi

+0

@Fordi Ответчик явно неправильно понял смысл «происхождения». С или -o вы получаете полную 1.3G истории Linux (что примерно в два раза больше фактической рабочей копии). –

+0

Er. Когда я говорю «это сработало», я имею в виду, что он сделал то, что было на олове. В сочетании с номинальным --depth = 1, чтобы ограничить набор исправлений, я получаю, я получил загрузку 150 Мп, при исправлении, которое я запросил. Не предполагается ли это? Должен ли я записывать отчет об ошибке? – Fordi

2

Используя 2 из вышеуказанных ответов (How to clone git repository with specific revision/changeset? и How to clone git repository with specific revision/changeset?) Помог мне придумать решительный. Если вы хотите клонировать до точки, то эта точка должна быть тегом/ветвью, а не просто SHA или FETCH_HEAD запутывается. После набора git fetch, если вы используете название ветки или тега, вы получаете ответ, если вы просто используете SHA-1, вы не получаете ответа.
Вот что я сделал: - создать полный рабочий клон полного репо, от фактического происхождения

cd <path to create repo> 
git clone [email protected]<our gitlab server>:ui-developers/ui.git 

Затем создать местное отделение, в точке, это интересно

git checkout 2050c8829c67f04b0db81e6247bb589c950afb14 
git checkout -b origin_point 

Затем создайте мое новое пустое репо с моей местной копией в качестве источника

cd <path to create repo> 
mkdir reduced-repo 
cd reduced-repo 
git init 
git remote add local_copy <path to create repo>/ui 
git fetch local_copy origin_point 

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

 
/var/www/html/ui-hacking$ git fetch local_copy origin_point 
remote: Counting objects: 45493, done. 
remote: Compressing objects: 100% (15928/15928), done. 
remote: Total 45493 (delta 27508), reused 45387 (delta 27463) 
Receiving objects: 100% (45493/45493), 53.64 MiB | 50.59 MiB/s, done. 
Resolving deltas: 100% (27508/27508), done. 
From /var/www/html/ui 
* branch   origin_point -> FETCH_HEAD 
* [new branch]  origin_point -> origin/origin_point 

Теперь в моем случае, я тогда нужно положить, что обратно на gitlab, как свежий репо, так что я сделал

git remote add origin [email protected]<our gitlab server>:ui-developers/new-ui.git 

Что означало, я мог бы восстановить мой репозиторий из origin_point с помощью git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k для вишни драфта удаленно затем использовать git push origin, чтобы загрузить всю партию обратно в свой новый дом.

Надежда, что помогает кому-то

+0

Можете ли вы объяснить, что вы имеете в виду, «FETCH_HEAD запутывается»? И как ваш «git fetch local_copy origin_point» отличается от «git fetch origin refs/tags/tmptag' от JamesGs? – not2qubit

+0

'git fetch local_copy origin_point' оставляет вас в состоянии с пустым каталогом с сокращенным репо, содержащим только' .git'. В этих инструкциях есть что-то еще. – not2qubit

2

Моя версия была комбинация принятых и наиболее upvoted ответов.Но это немного по-другому, потому что каждый использует SHA1, но никто не говорит вам, как получить его

$ git init 
$ git remote add <remote_url> 
$ git fetch --all 

теперь вы можете видеть все ветви & совершает

$ git branch -a 
$ git log remotes/origin/master <-- or any other branch 

Наконец, вы знаете, SHA1 о желании совершить

git reset --hard <sha1> 
0

Его простота. Вы просто должны установить вверх для текущей ветви

$ git clone repo 
$ git checkout -b newbranch 
$ git branch --set-upstream-to=origin/branch newbranch 
$ git pull 

Это все