Цифровой садик - приветственная

Цифровой садик - приветственная | Полный список всего, что тут есть | RSS | Подписаться через follow.it

05.12.2024

git

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

(вторая используемая иногда - fossil)

Странички

Мелкие памятки себе

В консоли кириллица отображается как \цифры

git config core.quotepath false

Только один файл из другой ветки

git checkout master -- path/name.ext

или

git restore --source master -- path/name.ext

https://stackoverflow.com/questions/2364147/how-to-get-just-one-file-from-another-branch - там есть ещё варианты.

Коммит не в ту ветку, что делать?!

git reset HEAD~ --soft # вернулись к предыдущему коммиту, но не удаляем изменения
git add .  # изменения застейджили
git stash # сохранили застейдженное в stash
git checkout имя-верной-ветки # переключились куда надо
git stash pop # извлекли сохранённое из stash

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

git add . # застейджили уже здесь
git commit -m "описание коммита" # закоммитили на нужное место

Сбросить изменения к последнему закоммиченному

git reset --hard HEAD

В отдельном файле:

git checkout путь/имяфайла

И если это новые файлы, которые не были даже добавлены:

git clean -i -d
  • -d - чтоб заглядывал в неотслеживаемые каталоги.
  • как вариант, можно использовать -n для того, чтоб посмотреть, что будет вычищено, и -f - чтоб таки сделать это.)
  • в –help можно прочитать ещё потенциально полезного. Например, -X позволяет убрать файлы, которые git игнорирует.

Срочно подправить ошибку, замеченную до пуша

git commit -a --amend --no-edit

Довнести все изменения, сообщение коммита не менять

Или

git reset --soft HEAD~

Сделать вид, что коммита не было, сохранить состояние файлов. Можно теперь закоммитить как надо.

detached head

If you want to delete your changes associated with the detached HEAD You only need to checkout the branch you were on, e.g.

git checkout master

Next time you have changed a file and want to restore it to the state it is in the index, don't delete the file first, just do

git checkout -- path/to/foo

This will restore the file foo to the state it is in the index.

If you want to keep your changes associated with the detached HEAD

git branch tmp # this will save your changes in a new branch called tmp. Очевидимо, вместо tmp можно любое другое название
git checkout master

If you would like to incorporate the changes you made into master, run git merge tmp from the master branch. You should be on the master branch after running git checkout master.

Добавить удалённый (remote) репозиторий уже существующему локальному

Например

git remote add origin git@gitlab.com:agnessa/emacs-config.git

«git@gitlab.com:agnessa/emacs-config.git» - очевидимо, конкретный удалённый реп.

Про удалённые (deleted) файлы

https://stackoverflow.com/questions/6017987/how-can-i-list-all-the-deleted-files-in-a-git-repository

git log --diff-filter=D --summary

Краше

git log --all --pretty=format: --name-only --diff-filter=D | sort -u

This will get you a list of all files that were deleted in all branches, sorted by their path:

git log --diff-filter=D --summary | grep "delete mode 100" | cut -c 21- | sort > deleted.txt

Локальные настройки имени и адреса

https://git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9F%D0%B5%D1%80%D0%B2%D0%BE%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-Git

Если в разных репозиториях нужно коммиты от разных Name+email.

git config --local user.name "Name"
git config --local user.email email@mysite.ru

Или залезть в .git/config репозитория и написать

[user]
        email = name@mysite.ru
        name = Name

Проверка настроек

Если хотите проверить используемую конфигурацию, можно использовать команду git config –list, чтобы показать все настройки, которые Git найдёт:

$ git config --list
user.name=John Doe
user.email=johndoe@example.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto

Некоторые ключи (названия) настроек могут отображаться несколько раз, потому что Git читает настройки из разных файлов (например, из /etc/gitconfig и ~/.gitconfig). В таком случае Git использует последнее значение для каждого ключа.

Также вы можете проверить значение конкретного ключа, выполнив git config <key>:

$ git config user.name
John Doe

Так как Git читает значение настроек из нескольких файлов, возможна ситуация когда Git использует не то значение что вы ожидали. В таком случае вы можете спросить Git об origin этого значения. Git выведет имя файла, из которого значение для настройки было взято последним:

$ git config --show-origin rerere.autoUpdate
file:/home/johndoe/.gitconfig	false

Настройка ключа для конкретного сервиса

Пишется в ~/.ssh/config.

Host shortname
     HostName that.address.name
     User username
     IdentityFile ~/.ssh/key_for_service
     PreferredAuthentications publickey
     IdentitiesOnly yes

Посмотреть историю изменений одного файла

git log -p -- path/filename.txt

Найти коммиты с появлением и удалением строки

В кавычках, разумеется, строка

git log -S '7b28ff06-ab13-4070-8dc2-fcbc9fe2f0b0'
  • this looks for differences that introduce or remove an instance of <string>. It usually means "revisions where you added or removed line with 'Foo'".
  • the –pickaxe-regex option allows you to use extended POSIX regex instead of searching for a string. Example (from git log): git log -S"frotz\(nitfol" –pickaxe-regex

    С регэкспом

git log -G<regexp> --branches --al

https://stackoverflow.com/questions/2928584/how-to-grep-search-committed-code-in-the-git-history

И без учёта регистра

git log -S foobar -i --oneline

or

git log --regexp-ignore-case -Sfoobar

or

git log -i -Sfoobar

Note that with 1.x git versions this option will not work with a regexps, only with a fixed string. It works with regexps only since git 2.0 and commit 218c45a, git 2.0, May 2014.

https://stackoverflow.com/questions/25384842/case-insensitive-git-pickaxe-search

Достать файл из коммита

git checkout b9d55fe7e7e48b106464dfad0285190ced2c78ea /path/to/filename
  • после слова checkout и перед путём - хэш подходящего коммита. вместо хэша можно указывать по истории, типа там сколько назад от HEAD и типа того.
  • путь к файлу - от корня репозитория

"git stripspace" - может убирать комментарии и ненужные пробелы

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

Дата последнего изменения файла

git log -1 --pretty="format:%ci" /path/to/repo/anyfile.any

-1 restricts it to the very last time the file changed

%ci is just one of the date formats you can choose from others here at https://git-scm.com/docs/pretty-formats

https://stackoverflow.com/questions/22497597/get-the-last-modification-date-of-a-file-in-git-repo

Пуш не пушится

error: src refspec <branchname> соответствует более чем одному
error: не удалось отправить некоторые ссылки в «<репозиторий>»

или

error: src refspec <branchname> matches more than one
error: failed to push some refs to '<repository>'

Гит не может понять, что конкретно я от него хочу. Что именно отправить-то надо. Вероятнее всего, почему-то образовался тег, совпадающий с именем ветки. Можно подробнее указать ветку (refs/heads/<branchname>), можно удалить тег.

Удалить тег:

git tag -d <tag>

Переименовать тег не судьба вообще. :)

Если хочется полно обратиться к тегу, это refs/tags/<tag>.

Полностью команда push - это

git push [options] <repository> <refspec>

, где refspec - это

<source>:<destination>

Обычно это ветки, но могут быть и теги. И теоретически можно завести ещё пространство имён под refs, но я пока понятия не имею, зачем это могло бы быть нужно.

pushurl – или пушить в несколько репозиториев разом

You can choose to provide the name of a remote which you had previously configured using git-remote, git-config or even by a manual edit to the $GIT_DIR/config file. The URL of this remote will be used to access the repository. The refspec of this remote will be used by default when you do not provide a refspec on the command line. The entry in the config file would appear like this:

[remote "<name>"]
        url = <URL>
        pushurl = <pushurl>
        push = <refspec>
        fetch = <refspec>

The <pushurl> is used for pushes only. It is optional and defaults to <URL>. Pushing to a remote affects all defined pushurls or all defined urls if no pushurls are defined. Fetch, however, will only fetch from the first defined url if multiple urls are defined.

Так вот, если этих пушурлов будет несколько в одном таком remote, то git push remote будет пушить по всем. Если remote – origin, так просто git push будет пушить по всем.

Источник – man git-push. Упоминание, что так бывает – в емаксочатике. :)

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

Недавно всё ещё работало, и вдруг внезапно отказывает в соединении.

При запросе ssh -vT git@example.server.name получается много всего вроде бы ок, в конце:

debug1: send_pubkey_test: no mutual signature algorithm
debug1: No more authentication methods to try.
git@example.server.name: Permission denied (publickey).

Вероятно, обновили ssh на версию, которая перестала по умолчанию признавать некоторый тип ключей. По нынешним временам это ssh-rsa. Так что надо включить их поддержку в конфиге или в конкретной команде:

PubkeyAcceptedKeyTypes +ssh-rsa
ssh -o 'PubkeyAcceptedKeyTypes +ssh-rsa' example.server.name

И всё станет ок. По крайней мере, можно воспользоваться этим, чтобы загрузить более надёжный ключ. ssh

Куда писать инфу - почему не только и не столько в описание коммита

Написать тест, который будет контролировать появление новых подобных ошибок в проекте. При настроенном CI - это мощнейший инструмент для будущих участников проекта.

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

https://www.nikialeksey.com/2019/10/26/long-commit-message.html

Special GitLab References

GFM [gitlab flavored markdown] recognized special references.

You can easily reference e.g. an issue, a commit, a team member or even the whole team within a project.

GFM will turn that reference into a link so you can navigate between them easily.

GFM will recognize the following:

@foo : for specific team members or groups @all : for the whole team #123 : for issues !123 : for merge requests $123 : for snippets 1234567 : for commits [file](path/to/file) : for file references

GFM also recognizes references to commits, issues, and merge requests in other projects:

namespace/project#123 : for issues namespace/project!123 : for merge requests namespace/project@1234567 : for commits

[2015-03-31 Вт 10:19]

Stash

Если кто-то еще не пользуется git stash, советую обратить на эту команду пристальное внимание. Более чем удобно, занимаясь одним делом, «отложить» текущую работу в сторону и отвлечься, скажем, на срочное исправление бага, даже если он находится в другом бранче. После исправления и коммита можно преспокойно вернуться к начатому.

i. hack-hack-hack ii. git stash iii. fix-fix-fix iv. git commit -a -m 'bugfix #31337' v. git stash pop

Те же, кто знает про git stash, посмотрите на последнюю строку — её отличие от apply в том, что откладываемые результаты не остаются во временном хранилище (посмотрите git stash list после нескольких примений stash!)

Если изменение было фактически законченным, можно оформить коммит не отходят от кассы — git stash save 'commit msg' [2015-03-04 Ср 07:31] %

Интерактивное добавление файла в индекс с выбором отдельных чанков (частный случай -i)

git add -p # [2015-03-04 Ср 07:34]

Проверка «здоровья» репозитория и удаление из него мусора.

  • git fsck. Даже без –full неплохая проверка.
  • git count-objects. Проверка, сколько объектов будет потеряно и объём освобождаемого места при перепаковке репозитория.
  • git gc. Переупаковка локальных репозиториев и другие виды повседневных задач.

[2015-03-04 Ср 07:35]

(git fsck –full — Все объекты, на которые никто не указывает.)

Настройки при клонировании

После клонирования хранилища команды git push или git pull автоматически отправляют и получают его по первоначальному адресу. Каким образом Git это делает? Секрет кроется в настройках, заданных при создании клона. Давайте взглянем:

git config --list

Опция remote.origin.url задает исходный адрес; origin — имя первоначального хранилища. Как и имя ветки master, это соглашение. Мы можем изменить или удалить это сокращённое имя, но как правило, нет причин для этого.

Если оригинальное хранилище переехало, можно обновить его адрес командой

git config remote.origin.url git://новый.url/proj.git

Опция branch.master.merge задает удаленную ветку по умолчанию для git pull. В ходе первоначального клонирования она устанавливается на текущую ветку исходного хранилища, так что даже если HEAD исходного хранилища впоследствии переместится на другую ветку, pull будет верно следовать изначальной ветке.

Этот параметр обращается только к хранилищу, которое мы изначально клонировали и которое записано в параметре branch.master.remote. При выполнении pull из других хранилищ мы должны указать нужную ветку:

git pull git://пример.com/other.git master

Это объясняет, почему некоторые из наших предыдущих примеров push и pull не имели аргументов.

[2014-09-29 Пн 20:10]

git clone ssh:user@host:port/path

.git/config для i2p

You have local tunnels set up as per the guide for pull.git.repo.i2p on port 9450 and push.git.repo.i2p on port 9451

You are linking the local Git repository to the hosted repository test.git. If the hosted repository is a fork, replace "test.git" with "base/fork.git" etc.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git://127.0.0.1:9450/test.git
    pushurl = ssh://username@127.0.0.1:9451/srv/git/test.git
    fetch = +refs/heads/*:refs/remotes/origin/*

vcsh (для хранения конфигов)

http://vcs-home.branchable.com/ - vcsh - способ хранить в git конфиги домашней папки так, что можно два соседних файла держать в разных репозиториях.

While it may appear that there's an overwhelming amount of documentation and while the explanation of the concepts behind vcsh needs to touch a few gory details of git internals, getting started with vcsh is extremely simple.

Let's say you want to version control your vim configuration:

vcsh init vim
vcsh vim add ~/.vimrc ~/.vim
vcsh vim commit -m 'Initial commit of my Vim configuration'
# optionally push your files to a remote
vcsh vim remote add origin <remote>
vcsh vim push -u origin master
# from now on you can push additional commits like this
vcsh vim push

If all that looks a lot like standard git, that's no coincidence; it's a design feature. [2015-03-08 Вс 20:57]

bup - backup system based on the git packfile format

Backup system based on the git packfile format, providing fast incremental saves and global deduplication (among and within files, including virtual machine images). Current release is 0.26, and the development branch is master.

git-annex – иногда смотрела в ту сторону

В целом поняла, что это тема для управления файлами через git и в том числе, когда сами файлы недоступны. Но пока моя голова не есть это мочь :)


Если у вас есть мысли, комментарии, предложения или отклики по поводу этой страницы или этого цифрового сада в целом, напишите мне сообщение на agnessa@agnessa.pp.ru. Мне ооочень интересно!

Задонатить.


An IndieWeb Webring 🕸💍