Страницы

Поиск по вопросам

Показаны сообщения с ярлыком svn. Показать все сообщения
Показаны сообщения с ярлыком svn. Показать все сообщения

четверг, 13 февраля 2020 г.

Как узнать к какой версии ревизии приведена моя копия svn?

#svn


Как узнать к какой версии ревизии приведена моя копия svn?    


Ответы

Ответ 1



Если стоит Subversion, "svn info" в директории с локальной копией. Если в windows с установленным TortoiseSVN, правой кнопкой на директории -> свойства. Закладка Subversion.

Ответ 2



Используйте команду svnversion. svn info не может дать полноценную информацию о ревизии рабочей копии, т.к. в SVN есть такое понятие как mixed-revision working copy обозначающее рабочую копию содержащую элементы относящиеся к сорвешенно разным ревизиям. А ещё svnversion удобен для использования во всяких скриптах.

воскресенье, 5 января 2020 г.

Чем отличается merge от commit?

#svn


Чем отличается merge от commit?
Когда комитим - заливаем, скажем, в главную ветку свои изменения. Когда мержим -
объединяем  свою копию с изменениями в главной ветке.
Когда нужно выложить проект в продакшн, переключаемся на trunk, мержим, а потом еще
и комитим, зачем второе действие?    


Ответы

Ответ 1



Если бы merge был бы эквивалентен merge + commit, то пользователь потерял бы возможность выполнять следующие действия: Целиком review'ить изменения в feature branch, которые появляются после merge --reintegrate. Решать conflict'ы и tree conflict'ы, которые возникли в результате операции merge.

Ответ 2



Дело в том, что commit - это не просто заливка изменений. Сущность этой операции заключается в том, что изменения, сделанные локально, преобразуются в изменения, которые могут быть успешно добавлены в репозиторий и зафиксированы в нём в виде очередной ревизии. При этом локальные изменения всегда выражены в виде различий относительно последней ревизии, о которой известно локально (т.е. ревизии, которая была во время последнего update), а в репозиторий могут быть добавлены лишь такие изменения, которые выражены в виде различий относительно последней ревизии самого репозитория. В простейшем случае, когда в репозиторий не было добавлено ничего со стороны, преобразование изменений сводится к тому, чтобы не делать ничего, поскольку изменения и так уже выражены в виде различий относительно последней ревизии в репозитории. Поэтому операция commit становится тривиальной и выглядит, как простая заливка изменений. В случае же, когда с момента последнего update в репозитории уже появилось что-то новое, попытка сделать тривиальный commit проваливается и приходится проходить всю процедуру полностью, т.е. сначала приспосабливать свои локальные изменения к тем другим изменениям, которые уже были зафиксированы в репозитории кем-то другим, и только потом заливать их и фиксировать. Когда мы заливаем в репозиторий изменения, сделанные в рабочей копии, необходимость делать commit в самом конце очевидна. Ведь в репозитории ещё нет наших локальных изменений, поскольку предыдущая попытка сделать тривиальный commit провалилась. Не так очевидна эта необходимость в ситуации, когда мы объединяем одну ветку с другой прямо в репозитории с помощью merge. Дело тут вот в чём. На самом деле, операция commit играет ещё и роль подтверждения. Заливка в репозиторий новых изменений как в тривиальном случае, так и после адаптации всегда выполняется после того, как пользователь увидел окончательный вариант, поэтому его подтверждение, необходимое для фиксации очередной ревизии, как бы подразумевается и даётся тем же самым commit'ом. А вот про объединение веток в репозитории такого сказать нельзя. Результат объединения веток обычно отличается от того, что было в последних ревизиях как одной ветки, так и другой. Он представляет собой совершенно новую ревизию. И даже в том случае, когда участие пользователя в самом объединении веток не требуется, от него всё равно требуется получить подтверждение после того, как будет получен окончательный вариант новой ревизии. Именно для этого и нужен commit после merge. Если объединение прошло на автомате, то commit играет лишь роль подтверждения, которое необходимо для фиксации любой ревизии в репозитории.

Ответ 3



Commit - означает выложить свою версию в репозиторий Update - означает выкачать версию из репозитория (обновить свою) Merge - означает внесение изменений в своей версии по сравнению с версией из репозитория. Обычно юзеру предоставляется возможность просмотра изменений (построчно) чтобы определить какие изменения из репо можно применить к своей версии (решение конфликтов). Diff - сравнение 2-х версий. Часто имеет смысл делать перед Merge или для просмотра изменений сделанных другим членом команды Checkout - выкачивание целиком исходников из репо. Как правило делается в самом начале работы Типовой паттерн работы такой: checkout → работаем → commit → перерыв → update (возможно с merge) → работаем → commit и т.д.

вторник, 31 декабря 2019 г.

Создание ветки только измененных файлов в GIT или SVN

#git #svn #контроль_версий #git_branch


Есть проект, в котором N - файлов. Периодически создается версия обновления, но в
обновление входят только измененные файлы. Хотим проект завести под систему контроля
версий, типа git или svn. 

Ищем решение, при котором можно было бы выделить все измененные файлы (например из
истории коммитов) автоматически вынесить их в отдельную ветку/branch. 

Подскажите, возможно ли такое?
    


Ответы

Ответ 1



о создании ветки — см. ниже простое решение если создавать ветку не требуется, а надо лишь получить список файлов, изменившихся между коммитом1 и коммитом2, то можно сделать примерно так: $ git log --name-only --pretty="format:" коммит1..коммит2 | grep -v '^$' | sort -u пояснения: --name-only — выводить ещё и имена изменённых файлов --pretty="format:" — вся служебная информация будет выведена как пустые строки grep -v '^$' — удалит эти пустые строки sort -u — удалит дубликаты из списка из получившегося списка можно сразу и архив получить. примерно так (сжатый архив запишется в файл /tmp/archive.tgz): $ tar -czf /tmp/archive.tgz $(git log --name-only \ --pretty="format:" коммит1..коммит2 | grep -v '^$' | sort -u) ещё про «красоту»: файлы в архиве будут иметь тот же путь, что и в репозитории: dir1/file1 file2 чтобы файлы в архиве «лежали» в каталоге, например, proga-1.0: proga-1.0/dir1/file1 proga-1.0/file2 можно команде tar добавить опцию --transform (поддерживается, насколько мне известно, только версией tar из операционной системы gnu): $ tar -czf /tmp/archive.tgz --transform "s,^,proga-1.0/," $(git log --name-only --pretty="format:" коммит1..коммит2 | grep -v '^$' | sort -u) репозиторий со скриптами предложенные выше «однострочники» я поместил в репозиторий под лицензией gplv3. getfiles [ revision..range ] — выдаёт список всех файлов, изменявшихся в промежутке revision..range. если аргумент пропущен, то скрипт выдаст список всех файлов. createarchive revision..range /path/to/archive.tgz [ prefix ] — создаёт указанный архив (см. выше). если указан prefix, он добавляется к именам файлов (слэш в конце префикса автоматически добавляется при необходимости). truncatehistory [ revision..range ] — удаляет из репозитория историю всех файлов, кроме тех, что изменялись в указанный revision..range. используйте с осторожностью! код этого скрипта базируется на вот этом ответе. о создании ветки обрезать историю только для одной ветки, не затрагивая остальные, несколько более сложное решение, чем предложенное ниже. а предлагаю я «обреза́ть» историю не в основном репозитории, а в отдельном его клоне. если возникнет необходимость видеть «обрезанную» историю в своём же репозитории — можно подключить «обрезанный» клон как второй remote. учтите, что история у всех файлов из этого клона полностью отлична от истории файлов в основном репозитории — начиная с самого первого коммита. поэтому вливать такой отдельно-стоящий набор коммитов в рабочий репозиторий я бы не рекомендовал: теоретически могут возникнуть проблемы с последующей жизнедеятельностью репозитория. скачайте файлы или склонируйте мой репозиторий со скриптами. путь к скриптам обозначим как /путь1 сделайте клон вашего репозитория в пустом каталоге: $ git clone адрес-вашего репозитория . запустите: /путь1/truncatehistory revision..range всё, история репозитория полностью переписана и включает только те файлы, которые изменялись в промежутке revision..range

Ответ 2



Вариант действий для любой SCM неверен методологически - предлагается дублировать информацию, и так имеющуюся в системе (коллекция измененных объектов между двумя метками в истории) Опять же любая SCM посредственно/плохо подходит для цели "хранилище коллекций артефактов", для этого есть более другие системы Чисто технически ничто не мешает для любого диапазона истории (в любой на выбор VCS) получать динамически список затронутых файлов для включения в патч-лист (команды будут различаться, но не методология), но правильнее - не адаптрировать возможности новой VCS под старый процесс, а переосмыслить процесс и возможно его изменить (хранение патчей в репо выглядит бессмысленной тратой времени и трудозатрат - натуральнее выглядит тегирование полного дерева и получение патча для деплоя обновления между тэгами, и это - не зависит от того, какая VCS используется) Ну и чисто рекомендация - не надо гнаться за модным и бежать на Git, хотя со ST уходить все же разумное решение

суббота, 21 декабря 2019 г.

Как узнать кто и когда добавил строку?

#svn


Есть файл A, в котором появилась определенная строка.
Предположим: if(1 == 1){...}

Как с помощью SVN определить кто автор этой строки(чей коммит привнес эту строку)
+ номер ветки.
    


Ответы

Ответ 1



То же доступно в TotroiseSVN: Клик правой по файлу в репозитории - Tortoise SVN -> Blame (опции на ваше усмотрение). Кликнув правой по строке с автором, можно посмотреть лог и предыдущий Blame.

Ответ 2



Вам нужен svn blame. Покажет последнего (или не последнего, а на конкретную ревизию) автора для каждой строчки. Пример по ссылке: $ svn blame -x -b http://svn.red-bean.com/repos/test/readme.txt 3 sally This is a README file. 4 jess Don't bother reading it. The boss is a knucklehead. 3 sally

воскресенье, 15 декабря 2019 г.

Добавить в решение другой проект из контроля версий

#visual_studio #git #svn


Допустим, есть какое-то решение, которое добавлено в SVN, в котором я собственно
сейчас работаю.

Можно ли из SVN добавить в текущее решение проект из другого решения, что бы внося
изменения в этот импортированный проект(например, библиотека), они так же  комитились
в своем первоначальном решении?

В интерфейсе, я что-то ничего похоже на то, что мне нужно, не нашел...

Может быть другие программы контроля версий это умеют делать?

P.S Честно, мало работал с контролем версий и может быть мой подход неправильный
и это делается как-то по другому.
    


Ответы

Ответ 1



Обязательно должно быть в Visual Studio? Вот как как это сделать в командной строке (отсюда): svn propset svn:externals 'akismet http://plugins.svn.wordpress.org/akismet/trunk' . akismet - Имя директории или файла для связи репозитория http://plugins.svn.wordpress.org/akismet/trunk - Путь до репозитория который вы хотите привязать . - Путь до директории где вы хотите иметь связь После запуска необходимо залить и обновить через svn commit and svn update

Как работать с svn через HTTP прокси на Ubuntu?

#http #svn #прокси


При попытке извлечения кода svn выдает следующую ошибку:  

svn: OPTIONS of 'http://...': Не удалось разрешить имя хоста `...': 
Host not found (http://...)

    


Ответы

Ответ 1



Нужно прописать параметры прокси в настройках svn. sudo nano /etc/subversion/servers [global] http-proxy-host = defaultproxy.whatever.com http-proxy-port = 7000

суббота, 14 декабря 2019 г.

Git не хочет делать push?

#svn #bitbucket #git


REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master)
$ git push -u origin master
Password for 'https://nickname@bitbucket.org':
error: src refspec master does not match any.
error: failed to push some refs to 'https://nickname@bitbucket.org/nickname/jquery-g
allery.git'

REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master)
$ git pull origin master
Password for 'https://nickname@bitbucket.org':
fatal: Couldn't find remote ref master
Unexpected end of command stream

Что не так, подскажите?
[ git status ]
REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master)
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       .hg/
#       .hgignore
#       README.md
#       css/
#       index.html
#       js/
nothing added to commit but untracked files present (use "git add" to track)

[ git add . ]
REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master)
$ git add .
fatal: LF would be replaced by CRLF in .hg/cache/branchheads

[ git remote rm origin ]
REAL@BENTLY /c/ls/sites/home/test.loc/www/jquery-gallery (master)
$ git remote rm origin

REAL@BENTLY /c/ls/sites/home/test.loc/www/jquery-gallery (master)
$ git remote add origin git@bitbucket.org:nickname/jquery-gallery.git

REAL@BENTLY /c/ls/sites/home/test.loc/www/jquery-gallery (master)
$ git push -u origin master
The authenticity of host 'bitbucket.org (206.223.241.182)' can't be established.

RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'bitbucket.org,206.223.241.182' (RSA) to the list of
known hosts.
Permission denied (publickey).
fatal: The remote end hung up unexpectedly

p.s. ip изменен.
[ обновился ] 
Перенес в другой каталог исходники:
REAL@BENTLY /c/localgit/jquery-gallery (master)
$ git push -u origin master
Permission denied (publickey).
fatal: The remote end hung up unexpectedly

[ Решение ]
Наверное больше для себя чем для кого-то оставлю заметку. 
В общем дело было в public key, ввел другой public key, который находится в файле 
C:\Documents and Settings\REAL\.ssh\id_rsa.pub    


Ответы

Ответ 1



Вероятно в вашем локальном репозитории не создан refspec для бранча master, т.к. репозиторий пустой. Выполните git status. В результате вы должны получить ответ, наподобие этого: # On branch master nothing to commit (working directory clean) Если ответ не содержит строки "On branch master", то нужно выполнить первый коммит. После этого push должен отработать.

Ответ 2



У меня тоже такая фигня случалась когда пытался использовать путь по https. Возможно такая фигня случается если репозиторий приватный и git не использует твои ssh ключи. Удали старый origin и добавь новый с другой урлой: git remote rm origin git remote add origin git@bitbucket.org:nickname/jquery-gallery.git Должно заработать.

понедельник, 9 декабря 2019 г.

В чем смотреть разницу между исходниками (текстом)?

#git #svn #поиск_программ #tfs


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

Иногда необходимо сравнить два участка кода, найти и проанализировать различия. Конечно,
есть вариант закоммитить один в SVN, подменить другим и смотреть различия. Но всё же
не хочется мусорить в истории коммитов.
    


Ответы

Ответ 1



Даже не знаю, почему все предлагают онлайн утилиты. Если нужно сравнить пять-десять строк, то это можно и ручками, а если нужно мегабайтные куски (не объязательно прямо код, есть много чего, что нужно сравнивать), то как по мне, только нативные приложения. А их вагон и тележка. Платные я не вижу смысла рассматривать, так как есть нормальные бесплатные. Хотя говорят, что araxis просто чудо, но я его не использовал. meld. Есть под линукс и винду, под виндой маленький недостаток - требует установленного питона и ещё немного библиотек. Под линуксом ставится с репозитория. Кроме как сравнить файлы, умеет работать с основной массой систем контроля версий (даже коммитить). Я лично пользуюсь и запускаю его как meld . в каталоге с проектом. Сразу видно какие файлы изменились. winmerge. Пока доступен только под винду, но обещают скоро и под линукс (кроссплатформенный). Но его интерфейс как то чуточку "староват". diffuse. Виндовс/Линукс. Ничего особого не увидел, но вот "сеточка" в коде как то не то. Но это на любителя.

Ответ 2



в программах контроля версий используется либо «нормальный» (--normal, по умолчанию), либо «унифицированный» (--unified, -u) форматы программы diff: $ diff файл1 файл2 1c1 < qwerty --- > qwerty1 $ diff -u файл1 файл2 --- "файл1" 2016-07-28 10:48:41.337854383 +0300 +++ "файл2" 2016-07-28 10:48:54.073854155 +0300 @@ -1 +1 @@ -qwerty +qwerty1

Ответ 3



Есть хороший плагин Compare для Notepad++

Ответ 4



Я этим пользуюсь. Радует что онлайн, плюс поделится можно https://www.diffchecker.com/diff

Ответ 5



Если у вас установлен TortoiseSVN или TortoiseGIT то вы можете использовать для сравнения TortoiseMerge, даже если файлы не версированы.

Ответ 6



Это целый сектор программ. На вики есть достаточно исчерпывающий список с перечислением особенностей и фич: https://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools

суббота, 30 ноября 2019 г.

В чем различия между Git и SVN?

#git #svn #контроль_версий


Вопрос, собственно выбора. Чем Git лучше или хуже SVN? Почему чаще от разработчиков
я слышу именно про Git и его удобства, чем про SVN, хотя как по мне, все что слышал
можно делать и в SVN.

Причём для обоих вариантов есть удобный Tortoise, что сводит общение с репозиториями
практически на один уровень.

Может просто что-то плохо рекламируют, а разницы вообще нет?
    


Ответы

Ответ 1



GIT распределяется, а SVN - нет. Другими словами, если есть несколько разработчиков работающих с репозиторием у каждого на локальной машине будет ПОЛНАЯ копия этого репозитория. Разумеется есть и где-то и центральная машина, с которой можно клонировать репозиторий. Это напоминает SVN. Основной плюс в том, что если вдруг у вас нет доступа к интернету, сохраняется возможность работать с репозиторием. Потом только один раз сделать синхронизацию и все остальные разработчики получат поолную историю. GIT сохраняет метаданные изменений, а SVN целые файлы. Это экономит место и время. Система создания branches, versions и прочее в GIT и SVN отличаются значительно. В GIT проще переключатся с ветки на ветку, делать merge между ними. В общем GIT я нахожу немного проще и удобнее, но бывают конечно иногда сложности. Но где их не бывает? Разумеется есть гораздо больше отличий, но я перечислил те, которые чаще всего встречаются при работе с репозиториями и на МОЙ взгляд наиболее важные.

Ответ 2



Git сложнее для освоения. Лично мне git предпочтительнее, позволяет мне проще сделать больше разного. Например реорганизовать порядок и содержание коммитов. Работа с ветками имхо удобнее и быстрее, через git stash удобно проверять перед коммитом что не забыл добавить вновь созданный файл. Удобнее переносить свои наработки в разные ветки - создать локально ветку, в ней вести разработку, потом просто сделать merge ветки, в svn же нужно просматривать лог на предмет нужных коммитов и переносить их ручками.

Ответ 3



Так же распределённость git может быть полезна при восстановлении данных. Был случай когда накрылся жесткий диск на сервере, и все удалось восстановить благодаря локальным копиям. (P.S конечно лучше иметь зеркальные RAID, но дно другого не исключает).

Ответ 4



Сначала у нас контора работала на svn без веток, потом начали активно использовать гит с ветками, сейчас я устроился в другую контору которая работает на svn с ветками, и если честно каждый раз когда приходится сливать ветки - я с такой грустью и тоской вспоминаю гит, как там всё было просто и удобно, интуитивно понятно, и как кропотливо приходится трястись над каждым конфликтом, над каждым изменённым файлом в обеих ветках, когда гит большую часть умел разруливать сам. А заливание каталогов в svn вообще убивает если честно.

Ответ 5



Я бы в качестве одного из краеугольных отличий назвал бы еще lock http://svnbook.red-bean.com/en/1.7/svn.advanced.locking.html git удобнее тем, что не надо бегать с криком "уберите замок пожалуйста". С другой стороны, встает ряд дополнительных вопросов с merge кода, который впрочем при должном навыке с помощью инструментов git нормально решается.

понедельник, 25 ноября 2019 г.

Как организовать работу с системами контроля версий для разработки нескольких проектов с общей основой?


Стоит следующая задача: мне надо создать хранилище, где будут разные файлы скрипто
(например, A). Также будет хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B). Когда я создаю новый проект — создается новое хранилище (например, C). 

Теперь мне нужно в С перенести стандартный набор из хранилища В. Потом мне нужн
из А перенести 2 скрипта в С. После этого я вижу, что в стандартных файлах (которые хранятся в В) есть ошибка. Я её исправляю и хочу залить как на В, так и на С. И так далее. То есть мне надо с ними 3-мя работать одновременно. 

Уже пробовал git и svn, ничего не получилось. Решение через git submodule не подходит
т.к. общие файлы нужно редактировать в конкретных проектах, и при этом иметь возможность подтягивать изменения в этих же файлах из основного набора.

В какой системе контроля версий и каким образом можно организовать хранилища дл
решения этой задачи? 
    


Ответы

Ответ 1



Важно: если для вашего языка есть хорошая система управления зависимостями, то приведённо здесь решение лучше не использовать. Потому что если она есть, гораздо проще сделать из основы отдельную библиотеку и устанавливать её, как зависимость. В Node.js — NPM-пакет, в Ruby — gem, в PHP — пакет Composer, в Rust — crate, и т. д. А то получится избыточность и могут добавиться хлопоты при обновлениях, которых можно избежать, изначально не используя систему контроля версий не по назначению. git может такое. Вообще у меня впечатление, что git может всё. Правда, механизм работы не слишко простой, нужно понимать, как он при этом будет работать. Поскольку git по природе своей распределённый, я сэмулирую ваш порядок работы в одно локальном репозитории на нескольких несвязанных ветках: a, b и master. Изменения в эти ветках могут запросто появляться из других репозториев (разные ветки могут следить за разными серверами!), но при использовании такой методики у вас локально должен быть репозиторий, в котором есть все три. Поехали по пунктам: Положим, что git init вы сделали, а С (сам проект) лежит в ветке master (что совершенно необязательно). создать хранилище, где будут разные файлы скриптов (например, A) Делаем "несвязанную ветку": git checkout --orphan a Зачищаем папку и индекс, чтобы начать с чистого листа: git reset && git clean -f Делаем коммит с фигнёй: echo 'скрипт' | tee script_a_1 script_a_2 git add . git commit # Тут вас попросят ввести сообщение для коммита хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B) То же самое. git checkout --orphan b git reset && git clean -f echo 'скрипт' | tee script_b_1 script_b_2 git add . git commit # Сообщение для коммита Когда я создаю новый проект - создается новое хранилище (например, C). Будем считать, что это ветка master. И в настоящий момент она должна быть пуста для git это означает, что она не существует, поэтому придётся делать её заново: git checkout --orphan master git reset && git clean -f Теперь мне нужно в С перенести стандартный набор с хранилища В. Мёрдж: git merge b При этом произойдёт fast-forward до b, master будет совпадать с веткой b. Это нормально. Ведь на этом этапе состояния файловой системы проекта совпадают, верно? Потом мне нужно с А перенести 2 скрипта в С. Мёрдж с a, но на сей раз с "тормозами", чтобы прямо перед коммитом git остановился: git merge --no-commit --no-ff a Зачем? Затем, что вам не все файлы нужны. На этом этапе вы можете убрать из индекс ненужные вам файлы из индекса с помощью reset, зачистить оставшееся и закоммитить результат: git reset script_a_2 git clean -f git commit Теперь немного "поработаем", для вида: echo work > work git add work git commit в стандартных файлах (которые хранятся в В) есть ошибка. Я ей исправляю и хоч залить как на В... Поскольку у вас (семантически) master основан на b, а не наоборот, ошибку вам над починить именно в b, чтобы потом изменения "растеклись" (не автоматически!) по тем, кто ею пользуется. Идём в ветку b и чиним: git checkout b # clean уже не нужен, т. к. ветка не пустая echo script > script_b_1 # Ну, допустим, что кириллица не переварилась. Мало ли. git add script_b_1 git commit На этом этапе, если репозитории с b и master всё-таки разные, должен быть git pus ветки b в соответствующий репозиторий, а в репозитории проекта нужно сделать git pul --ff-only (--ff-only разрешает только перемотку ветки — чтобы ваши изменения не "затекли" в b) в ветке, которая за тем репозиторием следит. Это уже отдельная тема, если интересно, расскажу и об этом. ...так и на С. Переходим в ветку с проектом: git checkout master И делаем мердж ветки b в проект. git merge b Готово. Да, вот так просто! После проделывания вышеописанных манипуляций, я получил в master следующую схем из коммитов (git log --graph): * commit 2e9219cb2922f70382a8f069fdc917bdbfccd4b8 |\ Merge: 2cc463a 1fc0b61 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:46:12 2015 +0300 | | | | мердж фикса | | | * commit 1fc0b61c1017acf4b4ef1941e1cdcb01a7e86be4 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:41:23 2015 +0300 | | | | фикс основы | | * | commit 2cc463ae97500bff4a304990aa4e42159da96fe9 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:38:37 2015 +0300 | | | | работа | | * | commit cfa122c954f77b3282f51511f94bc6d97c95d569 |\ \ Merge: 7da066c f9304d8 | |/ Author: Имя <адрес> |/| Date: Sun Dec 27 14:31:20 2015 +0300 | | | | мердж с удалением лишних | | | * commit f9304d82d89600add270544bec32cd6661a8c150 | Author: Имя <адрес> | Date: Sun Dec 27 13:46:39 2015 +0300 | | скриптики | * commit 7da066c234216057ff19775a355342ed501fe9a4 Author: Имя <адрес> Date: Sun Dec 27 13:54:01 2015 +0300 основа И для наглядности, перерисовал:

Ответ 2



Если не хочется делать несколько веток, отслеживающих разные сервера, и так дале как в другом ответе, то можно работать аналогично тому как разрабатываются крупные распределённые проекты вроде ядра Linux или языка Go - через файлы с патчами, с тем лишь отличием что ничего никому не нужно посылать по почте. Вносим изменения в файлы проекта C, которые нужно перенести обратно в A или B: git add -p; git commit У нас получился коммит в котором меняются файлы имеющие место только лишь в A или B, обязательно не одновременно. Проверяем это с помощью git show. Экспортируем этот коммит в файл: git format-patch -1 Команда создаёт файл с изменениями вида 0001-example.patch. Переходим в проект A или B, применяем там ранее полученный патч: git am ../ProjectC/0001-example.patch В лучшем случае ничего больше делать не надо. В худшем случае может потребоваться решить обычные конфликты, которые появляютс при слиянии. Например, так: find . -type f -name \*orig -print -delete find . -type f -name \*rej -print -delete patch -p1 < .git/rebase-apply/patch find . -name \*.rej | while read rej do echo $rej wiggle -r ${rej%.rej} $rej done Таким же образом изменения переносятся обратно. Вот и всё. Ограничение остаётся всё то же самое: для удобного и простого отслеживания истории файлы в проекте C должны оставаться там же где и в проектах A и B. То же относится к работе с несколькими проектами: чтобы переносить какое-то изменени из проекта-шаблона B в копии С1, С2, С3... При любом подходе вам нужно будет писать программу или скрипт. Недостатки такого подхода Недостатки очевидны - это относительно ручная работа для переноса изменений (которая в принципе поддаётся автоматизации), но и о достоинствах забывать не стоит. Достоинства такого подхода Самое очевидное достоинство такого подхода: простота при использовании и отсутстви необходимости помнить где какая ветка, а значит меньше шансов сделать merge не того не туда. Меньше ошибок - меньше времени на их исправление. Больше времени на более интересные занятия. Ещё одно достоинство: конфиденциальность. Если вам когда-либо нужно будет дать досту к Git посторонним (например, вашему подрядчику для проведения рутинных работ), то посторонний не увидит всей-всей истории изменений в проектах A и B, которая обязательно попадет в C при любом слиянии веток. Например, если вы начинаете новый проект из шаблона так: # начинаем новый проект git clone TemlateB NewProjectC cd NewProjectC git reset $(echo "NewProjectC Started" | git commit-tree HEAD^{tree}) git remote rm origin # спустя некоторое время git am ../TemlateB/0001-example-fix.patch То в такой ситуации в проекте C посторонний увидит только какой-то самый недавни коммит и коммиты-исправления, а не всю историю проектов A и B за всё время. Естественно, посторонний не увидит и изменений из других проектов, аналогичных C. Масштабируемость - ещё одно достоинство этого подхода. Поддерживать 30-50-80 копи проекта? Нет проблем! Делегировать работу над каким-то проектом подрядчику? Проще простого! Убрать какой-то проект в архив с глаз долой? Нет проблем! Вернуть из архива? Легко! Теперь представьте себе сколько экранов будут занимать 80+ веток по каждому из когда-либ начатых проектов. Даже и говорить не стоит о том чтобы убрать какую-то ветку в архив или делегировать что-то кому-то. Нет, нельзя сказать что это невозможно...

суббота, 13 июля 2019 г.

Большой проект с множеством модулей. Делать один репозиторий или несколько?

Есть большой проект. Сейчас все исходники хранятся на сервере. Исходники разложены по логическим каталогам. В каждом каталоге около 10 -15 проектов на c#. Всего порядка 500 таких проектов (выходит 500 dll). Сейчас разработчик заходит на сервер, берет нужный проект, правит его и выкладывает новые исходники. Компоненты одного проекта могут вызываться в другом. Т. е. есть определения связанность.
Каким образом можно внедрить Git или svn. Не ясно как сформировать репозиторий. Должен быть один большой или их следует дробить. Хотелось бы увидеть примеры внедрения таких систем, описание в статьях, например.


Ответ

Как это ни прискорбно, но выбор git vs svn, главным образом, зависит от интеллектуального уровня команды. svn менее гибкий, и в нем сложнее что-то натворить, и если команду устраивал вариант с общей папкой, то я бы посоветовал его, хотя бы для начала. Конвертация из svn в git делается легко.
А выбор один репозиторий vs много мелких зависит от того, насколько часто нужно вносить синхронные правки в несколько проектов, например, изменение общей библиотеки и всех использующих ее модулей. Если часто, то лучше один репозиторий. Также если все модули собраны в один проект и компилируются за один раз, то тоже лучше один репозиторий.

среда, 19 июня 2019 г.

Как сконвертировать SVN-репозиторий с Google Code в git?

Я так понял, Google Code закрывается и SVN-сервер больше не держит. Скачал source-archive.zip с него, внутри него лежат:
branches .svn tags trunk wiki
В trunk, который я тоже пытался checkout'ить, лежат .svn и все файлы проекта.
И, собственно, что со всем этим дальше делать? Так как сам я svn не знаю и хочу git, пытался копипастить команды из гугла (поэтому просьба не смеяться при чтении ниженаписанного :), но что-то не катит.
Пытался в git svn clone file:///path/to/directory или git svn clone file:///path/to/directory/trunk — ругается, что «No repository found».
svnserve -d -r /path/to/directory и просто svn checkout svn://localhost с разными вариациями ссылки — аналогично «No repository found».
subgit захотел от меня сервер в интернете, а где мне его взять-то, если svnserve отдавать отказался.


Ответ

К сожалению вы опоздали. Вся ваша история была удалена 25 января 2016 года. Все что вы можете сейчас сделать - это взять содержимое этого архива и закоммитить в git в качестве начального состояния.
PS папки .svn и все их содержимое коммитить точно не нужно.

суббота, 16 марта 2019 г.

Как работать с svn через HTTP прокси на Ubuntu?

При попытке извлечения кода svn выдает следующую ошибку:
svn: OPTIONS of 'http://...': Не удалось разрешить имя хоста `...': Host not found (http://...)


Ответ

Нужно прописать параметры прокси в настройках svn. sudo nano /etc/subversion/servers [global] http-proxy-host = defaultproxy.whatever.com http-proxy-port = 7000

пятница, 9 ноября 2018 г.

Как узнать кто и когда добавил строку?

Есть файл A, в котором появилась определенная строка. Предположим: if(1 == 1){...}
Как с помощью SVN определить кто автор этой строки(чей коммит привнес эту строку) + номер ветки.


Ответ

То же доступно в TotroiseSVN: Клик правой по файлу в репозитории - Tortoise SVN -> Blame (опции на ваше усмотрение).
Кликнув правой по строке с автором, можно посмотреть лог и предыдущий Blame.

Git не хочет делать push?

REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master) $ git push -u origin master Password for 'https://nickname@bitbucket.org': error: src refspec master does not match any. error: failed to push some refs to 'https://nickname@bitbucket.org/nickname/jquery-g allery.git'
REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master) $ git pull origin master Password for 'https://nickname@bitbucket.org': fatal: Couldn't find remote ref master Unexpected end of command stream Что не так, подскажите? [ git status ] REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master) $ git status # On branch master # # Initial commit # # Untracked files: # (use "git add ..." to include in what will be committed) # # .hg/ # .hgignore # README.md # css/ # index.html # js/ nothing added to commit but untracked files present (use "git add" to track) [ git add . ] REAL@BENTLY /c/LS/sites/home/test.loc/www/gallery (master) $ git add . fatal: LF would be replaced by CRLF in .hg/cache/branchheads [ git remote rm origin ] REAL@BENTLY /c/ls/sites/home/test.loc/www/jquery-gallery (master) $ git remote rm origin
REAL@BENTLY /c/ls/sites/home/test.loc/www/jquery-gallery (master) $ git remote add origin git@bitbucket.org:nickname/jquery-gallery.git
REAL@BENTLY /c/ls/sites/home/test.loc/www/jquery-gallery (master) $ git push -u origin master The authenticity of host 'bitbucket.org (206.223.241.182)' can't be established.
RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'bitbucket.org,206.223.241.182' (RSA) to the list of known hosts. Permission denied (publickey). fatal: The remote end hung up unexpectedly p.s. ip изменен. [ обновился ] Перенес в другой каталог исходники: REAL@BENTLY /c/localgit/jquery-gallery (master) $ git push -u origin master Permission denied (publickey). fatal: The remote end hung up unexpectedly [ Решение ] Наверное больше для себя чем для кого-то оставлю заметку. В общем дело было в public key, ввел другой public key, который находится в файле C:\Documents and Settings\REAL\.ssh\id_rsa.pub


Ответ

Вероятно в вашем локальном репозитории не создан refspec для бранча master, т.к. репозиторий пустой. Выполните git status. В результате вы должны получить ответ, наподобие этого: # On branch master nothing to commit (working directory clean) Если ответ не содержит строки "On branch master", то нужно выполнить первый коммит. После этого push должен отработать.

вторник, 9 октября 2018 г.

В чем различия между Git и SVN?

Вопрос, собственно выбора. Чем Git лучше или хуже SVN? Почему чаще от разработчиков я слышу именно про Git и его удобства, чем про SVN, хотя как по мне, все что слышал можно делать и в SVN.
Причём для обоих вариантов есть удобный Tortoise, что сводит общение с репозиториями практически на один уровень.
Может просто что-то плохо рекламируют, а разницы вообще нет?


Ответ

GIT распределяется, а SVN - нет. Другими словами, если есть несколько разработчиков работающих с репозиторием у каждого на локальной машине будет ПОЛНАЯ копия этого репозитория. Разумеется есть и где-то и центральная машина, с которой можно клонировать репозиторий. Это напоминает SVN. Основной плюс в том, что если вдруг у вас нет доступа к интернету, сохраняется возможность работать с репозиторием. Потом только один раз сделать синхронизацию и все остальные разработчики получат поолную историю. GIT сохраняет метаданные изменений, а SVN целые файлы. Это экономит место и время. Система создания branches, versions и прочее в GIT и SVN отличаются значительно. В GIT проще переключатся с ветки на ветку, делать merge между ними. В общем GIT я нахожу немного проще и удобнее, но бывают конечно иногда сложности. Но где их не бывает? Разумеется есть гораздо больше отличий, но я перечислил те, которые чаще всего встречаются при работе с репозиториями и на МОЙ взгляд наиболее важные.

вторник, 2 октября 2018 г.

Как организовать работу с системами контроля версий для разработки нескольких проектов с общей основой?

Стоит следующая задача: мне надо создать хранилище, где будут разные файлы скриптов (например, A). Также будет хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B). Когда я создаю новый проект — создается новое хранилище (например, C).
Теперь мне нужно в С перенести стандартный набор из хранилища В. Потом мне нужно из А перенести 2 скрипта в С. После этого я вижу, что в стандартных файлах (которые хранятся в В) есть ошибка. Я её исправляю и хочу залить как на В, так и на С. И так далее. То есть мне надо с ними 3-мя работать одновременно.
Уже пробовал git и svn, ничего не получилось. Решение через git submodule не подходит, т.к. общие файлы нужно редактировать в конкретных проектах, и при этом иметь возможность подтягивать изменения в этих же файлах из основного набора.
В какой системе контроля версий и каким образом можно организовать хранилища для решения этой задачи?


Ответ

Важно: если для вашего языка есть хорошая система управления зависимостями, то приведённое здесь решение лучше не использовать. Потому что если она есть, гораздо проще сделать из основы отдельную библиотеку и устанавливать её, как зависимость. В Node.js — NPM-пакет, в Ruby — gem, в PHP — пакет Composer, в Rust — crate, и т. д. А то получится избыточность и могут добавиться хлопоты при обновлениях, которых можно избежать, изначально не используя систему контроля версий не по назначению.
git может такое.
Вообще у меня впечатление, что git может всё. Правда, механизм работы не слишком простой, нужно понимать, как он при этом будет работать.
Поскольку git по природе своей распределённый, я сэмулирую ваш порядок работы в одном локальном репозитории на нескольких несвязанных ветках: a, b и master. Изменения в этих ветках могут запросто появляться из других репозториев (разные ветки могут следить за разными серверами!), но при использовании такой методики у вас локально должен быть репозиторий, в котором есть все три.
Поехали по пунктам:
Положим, что git init вы сделали, а С (сам проект) лежит в ветке master (что совершенно необязательно).
создать хранилище, где будут разные файлы скриптов (например, A)
Делаем "несвязанную ветку":
git checkout --orphan a
Зачищаем папку и индекс, чтобы начать с чистого листа:
git reset && git clean -f
Делаем коммит с фигнёй:
echo 'скрипт' | tee script_a_1 script_a_2 git add . git commit # Тут вас попросят ввести сообщение для коммита
хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B)
То же самое.
git checkout --orphan b git reset && git clean -f echo 'скрипт' | tee script_b_1 script_b_2 git add . git commit # Сообщение для коммита
Когда я создаю новый проект - создается новое хранилище (например, C).
Будем считать, что это ветка master. И в настоящий момент она должна быть пуста, для git это означает, что она не существует, поэтому придётся делать её заново:
git checkout --orphan master git reset && git clean -f
Теперь мне нужно в С перенести стандартный набор с хранилища В.
Мёрдж:
git merge b
При этом произойдёт fast-forward до b, master будет совпадать с веткой b. Это нормально. Ведь на этом этапе состояния файловой системы проекта совпадают, верно?
Потом мне нужно с А перенести 2 скрипта в С.
Мёрдж с a, но на сей раз с "тормозами", чтобы прямо перед коммитом git остановился:
git merge --no-commit --no-ff a
Зачем? Затем, что вам не все файлы нужны. На этом этапе вы можете убрать из индекса ненужные вам файлы из индекса с помощью reset, зачистить оставшееся и закоммитить результат:
git reset script_a_2 git clean -f git commit
Теперь немного "поработаем", для вида:
echo work > work git add work git commit
в стандартных файлах (которые хранятся в В) есть ошибка. Я ей исправляю и хочу залить как на В...
Поскольку у вас (семантически) master основан на b, а не наоборот, ошибку вам надо починить именно в b, чтобы потом изменения "растеклись" (не автоматически!) по тем, кто ею пользуется. Идём в ветку b и чиним:
git checkout b # clean уже не нужен, т. к. ветка не пустая echo script > script_b_1 # Ну, допустим, что кириллица не переварилась. Мало ли. git add script_b_1 git commit
На этом этапе, если репозитории с b и master всё-таки разные, должен быть git push ветки b в соответствующий репозиторий, а в репозитории проекта нужно сделать git pull --ff-only (--ff-only разрешает только перемотку ветки — чтобы ваши изменения не "затекли" в b) в ветке, которая за тем репозиторием следит. Это уже отдельная тема, если интересно, расскажу и об этом.
...так и на С.
Переходим в ветку с проектом:
git checkout master
И делаем мердж ветки b в проект.
git merge b
Готово. Да, вот так просто!
После проделывания вышеописанных манипуляций, я получил в master следующую схему из коммитов (git log --graph):
* commit 2e9219cb2922f70382a8f069fdc917bdbfccd4b8 |\ Merge: 2cc463a 1fc0b61 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:46:12 2015 +0300 | | | | мердж фикса | | | * commit 1fc0b61c1017acf4b4ef1941e1cdcb01a7e86be4 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:41:23 2015 +0300 | | | | фикс основы | | * | commit 2cc463ae97500bff4a304990aa4e42159da96fe9 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:38:37 2015 +0300 | | | | работа | | * | commit cfa122c954f77b3282f51511f94bc6d97c95d569 |\ \ Merge: 7da066c f9304d8 | |/ Author: Имя <адрес> |/| Date: Sun Dec 27 14:31:20 2015 +0300 | | | | мердж с удалением лишних | | | * commit f9304d82d89600add270544bec32cd6661a8c150 | Author: Имя <адрес> | Date: Sun Dec 27 13:46:39 2015 +0300 | | скриптики | * commit 7da066c234216057ff19775a355342ed501fe9a4 Author: Имя <адрес> Date: Sun Dec 27 13:54:01 2015 +0300
основа
И для наглядности, перерисовал:

понедельник, 1 октября 2018 г.

Как организовать работу с системами контроля версий для разработки нескольких проектов с общей основой?

Стоит следующая задача: мне надо создать хранилище, где будут разные файлы скриптов (например, A). Также будет хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B). Когда я создаю новый проект — создается новое хранилище (например, C).
Теперь мне нужно в С перенести стандартный набор из хранилища В. Потом мне нужно из А перенести 2 скрипта в С. После этого я вижу, что в стандартных файлах (которые хранятся в В) есть ошибка. Я её исправляю и хочу залить как на В, так и на С. И так далее. То есть мне надо с ними 3-мя работать одновременно.
Уже пробовал git и svn, ничего не получилось. Решение через git submodule не подходит, т.к. общие файлы нужно редактировать в конкретных проектах, и при этом иметь возможность подтягивать изменения в этих же файлах из основного набора.
В какой системе контроля версий и каким образом можно организовать хранилища для решения этой задачи?


Ответ

Важно: если для вашего языка есть хорошая система управления зависимостями, то приведённое здесь решение лучше не использовать. Потому что если она есть, гораздо проще сделать из основы отдельную библиотеку и устанавливать её, как зависимость. В Node.js — NPM-пакет, в Ruby — gem, в PHP — пакет Composer, в Rust — crate, и т. д. А то получится избыточность и могут добавиться хлопоты при обновлениях, которых можно избежать, изначально не используя систему контроля версий не по назначению.
git может такое.
Вообще у меня впечатление, что git может всё. Правда, механизм работы не слишком простой, нужно понимать, как он при этом будет работать.
Поскольку git по природе своей распределённый, я сэмулирую ваш порядок работы в одном локальном репозитории на нескольких несвязанных ветках: a, b и master. Изменения в этих ветках могут запросто появляться из других репозториев (разные ветки могут следить за разными серверами!), но при использовании такой методики у вас локально должен быть репозиторий, в котором есть все три.
Поехали по пунктам:
Положим, что git init вы сделали, а С (сам проект) лежит в ветке master (что совершенно необязательно).
создать хранилище, где будут разные файлы скриптов (например, A)
Делаем "несвязанную ветку":
git checkout --orphan a
Зачищаем папку и индекс, чтобы начать с чистого листа:
git reset && git clean -f
Делаем коммит с фигнёй:
echo 'скрипт' | tee script_a_1 script_a_2 git add . git commit # Тут вас попросят ввести сообщение для коммита
хранилище, где будет стандартный набор файлов для начала программирования сайта (например, B)
То же самое.
git checkout --orphan b git reset && git clean -f echo 'скрипт' | tee script_b_1 script_b_2 git add . git commit # Сообщение для коммита
Когда я создаю новый проект - создается новое хранилище (например, C).
Будем считать, что это ветка master. И в настоящий момент она должна быть пуста, для git это означает, что она не существует, поэтому придётся делать её заново:
git checkout --orphan master git reset && git clean -f
Теперь мне нужно в С перенести стандартный набор с хранилища В.
Мёрдж:
git merge b
При этом произойдёт fast-forward до b, master будет совпадать с веткой b. Это нормально. Ведь на этом этапе состояния файловой системы проекта совпадают, верно?
Потом мне нужно с А перенести 2 скрипта в С.
Мёрдж с a, но на сей раз с "тормозами", чтобы прямо перед коммитом git остановился:
git merge --no-commit --no-ff a
Зачем? Затем, что вам не все файлы нужны. На этом этапе вы можете убрать из индекса ненужные вам файлы из индекса с помощью reset, зачистить оставшееся и закоммитить результат:
git reset script_a_2 git clean -f git commit
Теперь немного "поработаем", для вида:
echo work > work git add work git commit
в стандартных файлах (которые хранятся в В) есть ошибка. Я ей исправляю и хочу залить как на В...
Поскольку у вас (семантически) master основан на b, а не наоборот, ошибку вам надо починить именно в b, чтобы потом изменения "растеклись" (не автоматически!) по тем, кто ею пользуется. Идём в ветку b и чиним:
git checkout b # clean уже не нужен, т. к. ветка не пустая echo script > script_b_1 # Ну, допустим, что кириллица не переварилась. Мало ли. git add script_b_1 git commit
На этом этапе, если репозитории с b и master всё-таки разные, должен быть git push ветки b в соответствующий репозиторий, а в репозитории проекта нужно сделать git pull --ff-only (--ff-only разрешает только перемотку ветки — чтобы ваши изменения не "затекли" в b) в ветке, которая за тем репозиторием следит. Это уже отдельная тема, если интересно, расскажу и об этом.
...так и на С.
Переходим в ветку с проектом:
git checkout master
И делаем мердж ветки b в проект.
git merge b
Готово. Да, вот так просто!
После проделывания вышеописанных манипуляций, я получил в master следующую схему из коммитов (git log --graph):
* commit 2e9219cb2922f70382a8f069fdc917bdbfccd4b8 |\ Merge: 2cc463a 1fc0b61 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:46:12 2015 +0300 | | | | мердж фикса | | | * commit 1fc0b61c1017acf4b4ef1941e1cdcb01a7e86be4 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:41:23 2015 +0300 | | | | фикс основы | | * | commit 2cc463ae97500bff4a304990aa4e42159da96fe9 | | Author: Имя <адрес> | | Date: Sun Dec 27 14:38:37 2015 +0300 | | | | работа | | * | commit cfa122c954f77b3282f51511f94bc6d97c95d569 |\ \ Merge: 7da066c f9304d8 | |/ Author: Имя <адрес> |/| Date: Sun Dec 27 14:31:20 2015 +0300 | | | | мердж с удалением лишних | | | * commit f9304d82d89600add270544bec32cd6661a8c150 | Author: Имя <адрес> | Date: Sun Dec 27 13:46:39 2015 +0300 | | скриптики | * commit 7da066c234216057ff19775a355342ed501fe9a4 Author: Имя <адрес> Date: Sun Dec 27 13:54:01 2015 +0300
основа
И для наглядности, перерисовал: