Git
Конспект по курсу на stepik.org https://stepik.org/course/3145/syllabus
- Course from Stepik
- 2. Использование существующих репозиториев
- 3. Обзор текущего состояния локального репозитория
- 4. Коммит изменений
- 5. Создание веток
- 6. Переход между коммитами
- 7. git pull & git push
- 8. git diff
- Gitea
- Полезные ссылки
- Git flow | GitHub flow | GitLab Flow
- Progit
- git status -s
- Index File
- Tips
Course from Stepik
2. Использование существующих репозиториев
При клонировании репозитория есть два варианта
- SSH
- HTTPS
Если клонировать через https, то и пушить гит будет через https, а при работе по https он будет спрашивать пароль, при работе через ssh он будет сразу пушить (такое поведение легко исправить через конфиг (в конфиге указывается метод взаимодействия))
Для работы по ssh нужно чтобы на сервере был добавлен Ваш ssh-ключ
При клонировании можно сразу указать новую директорию
git clone git@github.com:vandud/test.git ~/Documents/testgitrepo
Но это сработает только с несуществующей директорией (уже существующая директория имеет в себе хардлинки (.
и ..
))
Конфиги есть трех видов и хранятся в трех местах
- Глобальные для всего сервера\компьютера -
/etc/gitconfig
- ключ--system
- Глобальные для пользователя -
/home/$USER/.gitconfig
или/home/$USER/config/git/config
- ключ--global
- Конфиг для конкретного репозитория -
repodir/.git/config
Конфиги применяются в описаном порядке, то есть третий конфиг перекрывает все предыдущие
После установки git сразу нужно указать имя и емайл пользователя (эта информация передается в коммитах)
git config --global user.name "Ivan Dudin"
git config --global user.email s@vandud.ru
Команда git config --list
покажет текущие настройки
vandud@vandud-desktop:~/Documents/testgitrepo$ git config --list
user.name=Ivan Dudin
user.email=s@vandud.ru
Любой файл имеет два состояния
- проиндексированный - гит отслеживает его состояние и запоминает изменения
- непроиндексированный - гит не обращает на него внимания
Чтобы проиндексровать файл, нужно выполнить команду
git add
Чтобы запомнить состояние файла(ов)
git commit
Чтобы отправить информацию (коммиты) на сервер
git push
3. Обзор текущего состояния локального репозитория
Для обзора текущего состояния локального репозитория обычноиспользуют команду git status
К git status
можно добавлять ключ -s
, для краткого вывода
[vandud@thinkpad test]$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: a
new file: b
new file: c
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a
deleted: b
modified: c
Untracked files:
(use "git add <file>..." to include in what will be committed)
txt
[vandud@thinkpad test]$ git status -s
AM a
AD b
AM c
?? txt
git add
https://git-scm.com/docs/git-add
Команда git add FILE
добавляет файл в индекс гита
Индекс содержит в себе снапшот контента рабочего дерева и из него будет браться контент для следующего коммита
Таким образом после изменений в рабочей директории перед коммитом нужно выполнить команду add
чтобы добавить новые или модифицированные файлы в индекс
Она всего лишь добавляет контент файла на момент выполенения команды в индекс. Поэтому если после ее выполнения были сделаны еще изменения которые должны войти в один коммит с предыдущими, то нужно просто повторить команду add
для нужных файлов
-
-f
- добавить в индекс и игнорируемые файлы -
-i
- интерактивный режим -
-A/--all
- добавить в индекс все файлы в текущем поддереве
git status
https://git-scm.com/docs/git-status
Показывает состояние текущего расположения. Точнее показывает разницу между текущим состоянием и последним коммитом
При выводе краткого статуса возможно два варианта
XY PATH
XY ORIG_PATH -> PATH # когда файл был переименован
- X - статус в индексе
- Y - статус в рабочей директории
Значения статусов:
-
' '
= unmodified -
M
= modified -
A
= added -
D
= deleted -
R
= renamed -
C
= copied -
U
= updated but unmerged
git commit
Создает новый коммит содержащий в себе текущий контент индекса и переданное ему сообщение, которое описывает сделанные изменения
Коммитируемый контент может быть добавлен в коммит несколькими способами
-
git add
- добавляет файлы в индекс и коммит строится на основе индекса -
git rm
- удаляет файл и удаляет его из индекса - перечисление файлов как аргументов для команды commit (файлы должны быть известными гиту, с untracked файлами не прокатит)
- опция
-a
для команды commit, она автоматически приведет индекс к состоянию рабочей директории, то есть она добавит новые файлы в индекс, удалит удаленные, добавит измененные - интерактивный режим
Опция --dry-run
позволит увидеть все добавленное в индекс для следующего коммита (т.е. все что будет включено в следующий коммит)
-
-a
- описано выше -
--short/--porcelain
- то же что и dry-run только кратко -
--long
- то же что и dry-run -
--branch
- показывает ветвь и некоторую инфу -
-F
- файл для коммитного комментария[vandud@thinkpad test]$ git commit -F - <<eof zhopa niga mazafaka eof [master 706cb5d] zhopa niga mazafaka 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file
-
--author
- ` перезаписывает автора коммита[vandud@thinkpad test]$ git commit -m 'test author field' --author='I V Dudin <i@vandud.ru>' [master c58e9c6] test author field Author: I V Dudin <i@vandud.ru> 1 file changed, 17 insertions(+)
-
--date
- перезаписывает дату коммита -
-e
- позволяет отредактировать текст коммита взятый из файла-f
, коммитного объекта-C
или введенный через ключ-m
-
-q
- не выводить коммитное саммари[vandud@thinkpad test]$ git commit -m 'test author field' --author='I V Dudin <i@vandud.ru>' [master c58e9c6] test author field Author: I V Dudin <i@vandud.ru> 1 file changed, 17 insertions(+) [vandud@thinkpad test]$ git commit -m 'test author field' --author='I V Dudin <i@vandud.ru>' -q [vandud@thinkpad test]$
git log
Показывает историю коммитов (коммиты и некоторую инфу о них)
По умолчанию в обратно-хронологическом порядке (новее=выше)
-
git log -p
- покажет изменения внесенные каждым коммитом -
--all
- все коммиты. полезно когда сделал чекаут и указатель HEAD указывает на более старый коммит, тогда чтобы увидеть коммиты новее, нужно указать этот ключ -
-NUM
- можно огранить вывод, указать кол-во коммитов которые нужно отобразить - еще можно ограничить по дате коммита, since after until before
-
--stat
- покажет краткую статистику по каждому коммиту -
--pretty
- позволяет изменить формат отображения- short
- full
- fuller
- oneline
[vandud@thinkpad test]$ git log --pretty=oneline 760edd0f7e412540b27a9c5427bf763316777ae4 (HEAD -> master) test author field c58e9c6330e07cba5a96e8dbc07fdf6b058e81d2 test author field 706cb5d8e742e69452f437360f8324b443d78a7b zhopa niga mazafaka ea678985faa7e47ac41f26303131506284fa4cb6 test 80e290dcb97fec2769193ce1aae63b322a553e28 (origin/master, origin/HEAD) test push on sshlink (without login/password) ddcad045cd054bb4c8774e5f998681f63800e588 git test commit
-
format
- позволяет указать формат[vandud@thinkpad test]$ git log --pretty=format:"%h - %an, %ar : %s" 760edd0 - I V Dudin, 51 minutes ago : test author field c58e9c6 - I V Dudin, 83 minutes ago : test author field 706cb5d - Иван Дудин, 2 hours ago : zhopa niga mazafaka ea67898 - Иван Дудин, 28 hours ago : test 80e290d - Ivan Dudin Test, 1 year, 1 month ago : test push on sshlink (without login/password) ddcad04 - Ivan Dudin Test, 1 year, 1 month ago : git test commit
-
--graph
- показывает граф коммитов[vandud@thinkpad test]$ git log --pretty=oneline --graph * 760edd0f7e412540b27a9c5427bf763316777ae4 (HEAD -> master) test author field * c58e9c6330e07cba5a96e8dbc07fdf6b058e81d2 test author field * 706cb5d8e742e69452f437360f8324b443d78a7b zhopa niga mazafaka * ea678985faa7e47ac41f26303131506284fa4cb6 test * 80e290dcb97fec2769193ce1aae63b322a553e28 (origin/master, origin/HEAD) test push on sshlink (without login/password) * ddcad045cd054bb4c8774e5f998681f63800e588 git test commit [vandud@thinkpad test]$ git log --pretty=short --graph * commit 760edd0f7e412540b27a9c5427bf763316777ae4 (HEAD -> master) | Author: I V Dudin <i@vandud.ru> | | test author field | * commit c58e9c6330e07cba5a96e8dbc07fdf6b058e81d2 | Author: I V Dudin <i@vandud.ru> | | test author field | * commit 706cb5d8e742e69452f437360f8324b443d78a7b | Author: Иван Дудин <i.dudin@i-free.com> | | zhopa | niga | mazafaka | * commit ea678985faa7e47ac41f26303131506284fa4cb6 | Author: Иван Дудин <i.dudin@i-free.com> | | test | * commit 80e290dcb97fec2769193ce1aae63b322a553e28 (origin/master, origin/HEAD) | Author: Ivan Dudin Test <s@vandud.ru> | | test push on sshlink (without login/password) | * commit ddcad045cd054bb4c8774e5f998681f63800e588 Author: Ivan Dudin Test <s@vandud.ru> git test commit
-
-S
- типа греп по коммитам[vandud@thinkpad test]$ git log -S zhopa commit 760edd0f7e412540b27a9c5427bf763316777ae4 (HEAD -> master) Author: I V Dudin <i@vandud.ru> Date: Tue Dec 8 06:08:59 2020 +0300 test author field
- в самом конце команды или после знака
--
можно указать путь до папки или файла, будут отфильтрованы коммиты которые его затрагивают
Есть два понятия, коммитер и автор, они отличаются
git checkout
Переключение между ветвями или восстановление файлов в рабочей директории
Приводит файлы в рабочей директории к состоянию какой-либо версии из индекса
Переключение на ветвь это изменение файлов в соответствии с индексом и перевешивание указателя HEAD
HEAD – это указатель на коммит в вашем репозитории, который станет родителем следующего коммита
-
-b
- название новой ветки
4. Коммит изменений
macbook:test vandud$ git rm govno
rm 'govno'
macbook:test vandud$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: govno
macbook:test vandud$ git commit -m 'zhopa23'
[master fb6a8c6] zhopa23
1 file changed, 1 deletion(-)
delete mode 100644 govno
macbook:test vandud$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
macbook:test vandud$
Выше видно как я сделал git rm
(он удаляет файл и сразу же добавляет это изменение в индекс)
Далее видим что в статусе сразу видно это удаление и предлагается сделать коммит
Делаю коммит и в статусе видно что моя текущая копия впереди от ориджина на один коммит (предлагается запушить)
.gitignore
macbook:test vandud$ cat .gitignore
*.zhopa
macbook:test vandud$ vim zhopa.zhopa
macbook:test vandud$ git status -s
?? .gitignore
macbook:test vandud$ git add zhopa.zhopa
The following paths are ignored by one of your .gitignore files:
zhopa.zhopa
Use -f if you really want to add them.
Файл .gitignore нужен для вывода антрэкед файлов из поля зрения гита. Уже затреченые файлы он продолжит видеть не смотря на гитигнор
По формату файла можно смотреть тут - https://git-scm.com/docs/gitignore
macbook:test vandud$ git add -f zhopa.zhopa
macbook:test vandud$ git status -s
A zhopa.zhopa
?? .gitignore
git-add
Добавляет контент файлов в индекс
Можно перечислять файлы поименно, можно использовать ключ -A/--all
, можно использовать шаблоны как в .gitignore
-
-f
- добавит не смотря на гитигнор -
--dry-run
- не добавит файлы, покажет что с ними произойдет при обычном добавлении
macbook:test vandud$ git add --dry-run au.zhopa
The following paths are ignored by one of your .gitignore files:
au.zhopa
Use -f if you really want to add them.
macbook:test vandud$ git add --dry-run aou.aeou
add 'aou.aeou'
macbook:test vandud$ git status -s # видим что ничего не добавилось
A zhopa.zhopa
?? .gitignore
?? aou.aeou
Чтобы обновить инфу об удаленных файлах в индексе, нужно добавить их командой add
macbook:test vandud$ touch test
macbook:test vandud$ git status -s
?? test
macbook:test vandud$ git add test
macbook:test vandud$ git status -s
A test
macbook:test vandud$ rm test
macbook:test vandud$ git status -s
AD test
macbook:test vandud$ git add test
macbook:test vandud$ git status -s
macbook:test vandud$
git-rm
Удаляет файл(ы) и обновляет индекс, принимает имена файлов или шаблоны
Не даст удалить проиндексированный но не закоммиченный файл
Чтобы все равно удалить, нужно использовать ключ -f/--force
macbook:test vandud$ git add aou.aeou
macbook:test vandud$ git rm aou.aeou
error: the following file has changes staged in the index:
aou.aeou
(use --cached to keep the file, or -f to force removal)
macbook:test vandud$ git commit -m 'test rm'
[master cc5a978] test rm
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 aou.aeou
macbook:test vandud$ git rm aou.aeou
rm 'aou.aeou'
macbook:test vandud$ git status -s
D aou.aeou
?? .gitignore
А вот так с ключом -f
macbook:test vandud$ touch test
macbook:test vandud$ git status -s
D aou.aeou
?? .gitignore
?? test
macbook:test vandud$ git add test
macbook:test vandud$ git status -s
R aou.aeou -> test
?? .gitignore
macbook:test vandud$ git rm test
error: the following file has changes staged in the index:
test
(use --cached to keep the file, or -f to force removal)
macbook:test vandud$ git rm -f test
rm 'test'
macbook:test vandud$ git status -s
D aou.aeou
?? .gitignore
-
--cached
- удалит из индекса но оставит сам файл
macbook:test vandud$ git status -s
A zhopa.zhopa
?? .gitignore
?? aou.aeou
macbook:test vandud$ cat zhopa.zhopa
santoehu
macbook:test vandud$ git rm --cached zhopa.zhopa
rm 'zhopa.zhopa'
macbook:test vandud$ git status -s
?? .gitignore
?? aou.aeou
macbook:test vandud$ cat zhopa.zhopa
santoehu
git-commit
"Слепок индекса"
-
-a
- загонит состояние директории в индекс
(удалит удаленное, обновит измененное, добавит новое итд)
В гит коммит можно передать имена файлов, тогда будут закоммичены только изменения из них и будет проигнорирован индекс
-
--amend
- изменить последний неопубликованный коммит (объединить последний коммит с тем что коммитится в момент выполнения команды)
macbook:test vandud$ git log --oneline
cc5a978 (HEAD -> master) test rm
fb6a8c6 zhopa23
5876123 (origin/master) govno
3993fdf rm
6b356d6 double zhop commit
6cdf909 zhopnyi commit
macbook:test vandud$ git status -s
D aou.aeou
?? .gitignore
macbook:test vandud$ git add .gitignore
macbook:test vandud$ git status -s
A .gitignore
D aou.aeou
macbook:test vandud$ git commit -m '--amend test' --amend
[master 176e908] --amend test
Date: Sun Feb 7 05:09:54 2021 +0300
1 file changed, 1 insertion(+)
create mode 100644 .gitignore
macbook:test vandud$ git status -s
macbook:test vandud$ git log --oneline
176e908 (HEAD -> master) --amend test
fb6a8c6 zhopa23
5876123 (origin/master) govno
3993fdf rm
6b356d6 double zhop commit
6cdf909 zhopnyi commit
5. Создание веток
git branch - создает новую ветвь
git checkout - переключает на ветвь
git checkout -b - объединяет две пред. команды
git merge - мерджит указанную ветвь в текущую
git-checkout - позволяет переключаться между ветками (коммитами, тегами) или восстановить файлы рабочего каталога
git checkout [options] [<branch>]/<commit>/<tag>
git checkout [options] <file_name_to_restore>
-f --force - Позволяет переключиться между ветками, даже если состояние файлов отличается от состояния, обозначенного как HEAD. Может использоваться для отмены локальных изменений
-b <new_branch> - Создаёт новую ветку с именем <new_branch>; для получения дополнительной информации см. git-branch
Переход к другой ветке - git checkout master
Переход к коммиту с тегом HEAD - git checkout HEAD
Переход к коммиту, предшествующему HEAD на 4 - git checkout HEAD~4
Найти хеш коммита с использованием git log и перейти к этому коммиту:
git log --grep="Commit message fragment"`
git checkout b20eb8bdb8daf5fcec3ceb191c6b9b25507376ca
Отменить незакоммиченные изменения в файле file.txt - git checkout -- file.txt
box@47f08793a3e6: ~/REPO $ git branch --list *5555
15Qy1C1hC8BdGenCuGQthMZhaOk4l7vJ_5555
macbook:test vandud$ git branch # local
aoeuaoeu
master
new_test_branch
* vandud
macbook:test vandud$ git branch --list # local
aoeuaoeu
master
new_test_branch
* vandud
macbook:test vandud$ git branch --all # all
aoeuaoeu
master
new_test_branch
* vandud
remotes/origin/master
remotes/origin/vandud
macbook:test vandud$ git branch -r #remote
origin/master
origin/vandud
Удалять ветки можно с помощью git branch -d/-D <branchname>
С сервера ветки можно удалять так git push <reponame> --delete <branchname>
macbook:test vandud$ git branch -a
* master
remotes/origin/master
remotes/origin/testus
remotes/origin/vandud
macbook:test vandud$ git push
Everything up-to-date
macbook:test vandud$ git push origin --delete testus
remote: . Processing 1 references
remote: Processed 1 references in total
To https://gitea.vandud.ru/vandud/test.git
- [deleted] testus
macbook:test vandud$ git push origin --delete vandud
remote: . Processing 1 references
remote: Processed 1 references in total
To https://gitea.vandud.ru/vandud/test.git
- [deleted] vandud
macbook:test vandud$ git branch -a
* master
remotes/origin/master
macbook:test vandud$
Интересный факт
macbook:test vandud$ git log --all --graph --oneline
* 0ba27fa (origin/master) clear working tree
* 27b74a8 (HEAD -> master) dick
* 2132219 Merge branch 'vandud'
|\
| * 59b8d9f aoue
| * 80ba1f4 govno
...
macbook:test vandud$ git branch 59b8d9f
macbook:test vandud$ git checkout 59b8d9f
warning: refname '59b8d9f' is ambiguous. # <-- "ambiguous" - говорит о том что имя неоднозначное
D govno
D mazafaka
D new.tt
Switched to branch '59b8d9f' # <-- и в итоге свитчится на бранч
6. Переход между коммитами
git log
git log - позволяет просматривать историю коммитов, производить поиск по тексту сообщений в коммитах, по измененным файлам, по датам, по авторам, по веткам и прочим параметрам
По умолчанию история коммитов выводится в обратном хронологическом порядке (выше - новее)
- -p - full-diff, показыавет дифф от коммита
Также можно управлять выводом деталей в git log при помощи готовых пресетов и параметра --pretty
. Доступные пресеты: oneline, short, full и fuller
Пример использования:
git log --pretty=oneline
111111 commit1
222222 commit2
333333 commit3
Кроме того, git log позволяет полностью настроить формат вывода при помощи параметра format
Пример использования format:
git log --pretty=format:"%h - %an, %ar : %s"
1111111 - Name Surname, 9 months ago : commit1
2222222 - Name Surname, 10 months ago : commit2
3333333 - Name Surname, 11 months ago : commit3
Где %h
- хэш коммита, %an
- имя автора, %ar
- относительная дата, %s
- сообщение коммита
git checkout подходит не только для переключения между ветками, но и между коммитами и тегами:
git checkout [options] [<branch>]/<commit>/<tag>
git checkout [options] <file_name_to_restore>
git log --all --grep='commit message' # позволит отыскать коммит мессадж
Пример решения задачки со степика
box@b888ffedb096: ~/REPO $ git log --all --grep='Git rules!' --pretty=format:%H
> /home/box/answer
git stash
https://www.git-scm.com/docs/git-stash
Эта команда нужна для сохранения изменений которые по каким-то причинам не нужно включать в коммит. Например при переключении между ветками
stash сохраняет текущее состояние репозитория без создания коммита
Сохраняются только измененные отслеживаемые файлы
Неотслеживаемые файлы в stash не включаются
Сохранить незакоммиченную информацию перед переключением ветки можно было бы с помощью squash'a, но stash подходит лучше (squash позволяет объединять коммиты в один)
git stash
- эквивалентна git stash push
, которая сохраняет текущее состояние в стэш
Посмотреть записи в стэше можно с помощью git stash list
Стэш существует назависимо от бранчей
WIP - work in progress
git stash pop/apply
- позволяют извлечь состояние из стэша
После команды pop/apply указывается индекс записи в стэше, если не указать то будет взята последняя
Для удаления записей из стэша - git stash drop
git reset
Указатель HEAD указывает на указатель вершины ветки (например master)
macbook:test vandud$ git log --all --oneline
0ba27fa (HEAD -> master, origin/master) clear working tree
27b74a8 dick
2132219 Merge branch 'vandud'
...
macbook:test vandud$ git reset --soft HEAD~
macbook:test vandud$ git log --all --oneline
0ba27fa (origin/master) clear working tree
27b74a8 (HEAD -> master) dick
2132219 Merge branch 'vandud'
59b8d9f aoue
...
- git checkout - перетаскивает указатель HEAD
- git reset - перетаскивает указатель вершины ветки
У git reset есть три важных ключа
-
--soft
- перемещается HEAD, но индекс и рабочий каталог не меняется -
--mixed
- soft + изменение индекса -
--hard
- mixed + изменение рабочего каталога
То есть checkout переключает нас на какой-то коммит, а reset откатывает
7. git pull & git push
git fetch
Позволяет скачивать объекты и ссылки с удаленного репозитория
-
--all
- скачать все -
-t/--tags
- скачать все теги
git fetch origin
- обновить состояние всех веток в соответствии с репозиторием origingit fetch -t
- скачать все метки
Если необходимо скачать только новые файлы с удалённого репозитория, не обновляя существующие на локальном, то подходит команда git fetch
git pull
Скачать и синхронизироваться с репозиторием
git pull [opts] [<repo> [<refspec> ..]]
Слить удаленную ветку next в текущую
git pull origin next
Пример
Локально закоммитили и запушили
После этого на сервере кто-то закоммитил
Делаем изменения у себя локально без коммита
Пытаемся спуллить
Возникнет конфликт
git push
-
<repository>
- Имя или URL удалённого репозитория, на который необходимо загрузить данные -
<refspec>
- указывает, какую ссылку необходимо обновить в соответствии с каким объектом. Пример использования: "+<объект>:<ссылка>" -
--all
- Загрузить все ветки (то есть refs/heads/); не может быть использован вместе с <refspec> -
--delete
- Удалить все перечисленнык ссылки с удалённого репозитория. Имеет тот же самый эффект, что и запись ":<ссылка>" -
-f --force
- Обычно невозможно обновить ссылку на удалённом репозитории, если объект, который необходимо перезаписать, не был предком нового объекта. Для решения этой проблемы можно воспользоваться этим ключом
Загрузить изменения в конкретную ветку на удалённом репозитории
git push origin branch_name
Разрешение конфликтов
Конфликт - это ситуация, когда, в ходе слияния (pull/push/merge) система не может решить какие изменения нужно сохранить
Чаще всего такое бывает когда из одного коммита создано несколько веток и в один и тот же файл внесены изменения без синхронизации между ветками
Пример
Из мастера ответвились дважды и наделали независимых изменений
Далее смерджили первую ветку в мастер (все окей)
А когда попытаемся смерджить вторую ветку в мастер - будет конфликт
Внутри конфликтного файла будет такое
<<<<<<< HEAD
Changes from branch2
=======
Changes from branch1
>>>>>>> master
- между
<<<<<<< HEAD
и=======
- изменения, которые были внесены в текущей ветке/версии - между
=======
и>>>>>>> master
- изменения, которые были в ветке master на момент слияния (может быть указан хэш коммита вместо названия ветки)
Упрощенное разрешение конфликтов
git checkout --ours README.md # оставляем изменения из текущей ветки (отвергаем изменения из ветки которую мерджим в текущую)
git checkout --theirs README.md # наоборот
(логика простая, либо оставляем НАШЕ, либо оставляем ИХ)
Далее git add, git commit и все становится хорошо
Ручное разрешение конфликтов
Ручное разрешение конфликтов подходит в ситуациях, когда необходимы изменения, добавленные во всех конфликтующих ветках. Например, если в branch1 были добавлены стили, а в branch2 исправлены ошибки текста. Для ручного разрешения конфликта необходимо проделать следующее во всех конфликтных файлах (причем конфликт может возникать в нескольких местах одного файла):
- Удалить метки, которые добавил git
- Оставить одну, наиболее подходящую версию изменений
Для всех файлов с исправленным конфликтом необходимо сделать git add, после чего закоммитить и повторить операцию слияния
В данном примере, конфликт можно было спровоцировать, проделав git pull branch2 из ветки branch1 или наоборот. Алгоритм разрешения конфликтов в подобной ситуации аналогичен
8. git diff
git diff
- позволяет увидеть изменения в отслеживаемых файлах, но которые еще не были внесены в индекс
Команда может быть выполнена для отдельного файла или для всего репозитория
git diff
- сравнение рабочей директории и последнего коммитаgit diff --cached
- разница между индексом и последним коммитомgit diff HEAD
- изменения в рабочем дереве с момента последнего коммита; т.е. то, что будет закоммичено, если вы запустите «git commit -a»
Сравнение с произвольными коммитами:git diff test
- Сравнение с веткой «test»git diff HEAD -- ./file.txt
- Сравнение с текущей веткой, но diff ограничен только изменениями в файле "file.txt"git diff HEAD^ HEAD
- Сравнение последнего и предпоследнего коммита
Сравнение веток:git diff topic master
- Разница веток topic и mastergit diff topic...master
- Изменения, произошедшие в ветке master с тех пор, как ветка topic была создана
Ограничение вывода команды git diff:git diff --diff-filter=MRC
- Показывать только изменения, переименование и копирование (modification, rename, copy), но не добавление или удалениеgit diff --name-status
- Показывать только названия и характер изменений, но не фактический вывод git diff
git diff arch/i386 include/asm-i386
- Ограничить вывод git diff для указанных поддеревьев
Можно также делать
git diff COMMIT1 COMMIT2
Gitea
Гитея развернута на phobos'e
Устанавливал по офф. доке https://docs.gitea.io/en-us/install-from-binary/
Команда для создания юзера для демона
adduser —system —shell /bin/bash —gecos 'Gitea' \
—group —disabled-password —home /home/gitea gitea
Автозапуск сделан через systemd (в офф. доке написано как сделать)
Команда gitea dump -c /etc/gitea/app.ini
делает дамп в котором есть все что нужно для разворачивания
Сбросить пароль
root@phobos:~# sudo -u gitea gitea admin change-password --username vandud --password ZzaoeuAOEUeee....5Qc4YP --config /etc/gitea/app.ini
2021/01/24 03:38:55 ...dules/setting/git.go:91:newGit() [I] Git Version: 2.20.1, Wire Protocol Version 2 Enabled
vandud's password has been successfully updated!
root@phobos:~#
Полезные ссылки
Git flow | GitHub flow | GitLab Flow
Если не устанавливать никаких правил работы с ветками, в репозитории начинает расти энтропия:
- Появляется много долгоживущих веток,
- Вносимые изменения оказываются размазанными по разным веткам,
- Непонятно, откуда начинать разработку новой фичи или откуда разворачивать код на production.
Git Flow
Предполагает наличие основной ветки master
, ветки для накопленных изменений develop
, а также отдельных веток для фич, релизов и хотфиксов
Разрабатываемые изменения мержатся в develop
, оттуда в релизные ветки, и в итоге попадают в master
Нередко разработчики по ошибке мержат какие-то изменения только в master, забывая про develop. А большинство графических интерфейсов к git по умолчанию считают основной веткой именно master, поэтому в них приходится каждый раз что-то переключать или настраивать
Появляется лишняя сложность из-за веток релизов и хотфиксов. Большинство команд, особенно небольших, может легко обойтись без них
Поэтому это избыточно и не удобно
GitHub Flow
Самая простая модель
Здесь есть только master
и feature
-ветки
Мерджить в мастер и часто деплоиться - круто, но остается много других вопросов
GitLab Flow
GitLab flow: ветка production
Здесь мы можем настроить автодеплой при любом изменении в ветке production
Мерджить в master
можно когда угодно
А мерджить в production
из master
будем тогда когда нам удобно
GitLab flow: ветки для нескольких сред
Предположим, что у вас есть несколько сред: стейджинг (staging), пре-продакшен (pre-production) и продакшен (production). Код из master автоматически развёртывается на стейджинг. Как только вы готовы развернуть его на пре-продакшен, вы создаете мерж-реквест из master
в pre-production
. Соответственно, мерж из pre-production
в production
означает окончательный релиз. Такой процесс, когда все коммиты проходят через ветки в строго определенном порядке, гарантирует, что изменения прошли тестирование во всех средах
GitLab flow: релизные ветки
Это удобно при предоставлении ПО внешним клиентам. Здесь каждая минорная версия хранится в отдельной ветке
Следуйте правилу "upstream first": всегда, когда это возможно, сначала делайте мерж исправлений в master, и только оттуда — cherry-pick в релизную ветку. Благодаря этому правилу вы не забудете сделать cherry-pick исправлений в master и не встретите тот же самый баг в следующем релизе
Progit
1. Введение
Основное отличие Git от любой другой СКВ (включая Subversion и её собратьев) — это подход к работе со своими данными. Концептуально, большинство других систем хранят информацию в виде списка изменений в файлах. Эти системы (CVS, Subversion, Perforce, Bazaar и т. д.) представляют хранимую информацию в виде набора файлов и изменений, сделанных в каждом файле, по времени (обычно это называют контролем версий, основанным на различиях).
Git не хранит и не обрабатывает данные таким способом. Вместо этого, подход Git к хранению данных больше похож на набор снимков миниатюрной файловой системы. Каждый раз, когда вы делаете коммит, то есть сохраняете состояние своего проекта в Git, система запоминает, как выглядит каждый файл в этот момент, и сохраняет ссылку на этот снимок. Для увеличения эффективности, если файлы не были изменены, Git не запоминает эти файлы вновь, а только создаёт ссылку на предыдущую версию идентичного файла, который уже сохранён. Git представляет свои данные как, скажем, поток снимков.
Это очень важное отличие между Git и почти любой другой СКВ. Git переосмысливает практически все аспекты контроля версий, которые были скопированы из предыдущего поколения большинством других систем. Это делает Git больше похожим на миниатюрную файловую систему с удивительно мощными утилитами, надстроенными над ней, нежели просто на СКВ.
В Git для всего вычисляется хеш-сумма, и только потом происходит сохранение. В дальнейшем обращение к сохранённым объектам происходит по этой хеш-сумме. Это значит, что невозможно изменить содержимое файла или каталога так, чтобы Git не узнал об этом. Данная функциональность встроена в Git на низком уровне и является неотъемлемой частью его философии. Вы не потеряете информацию во время её передачи и не получите повреждённый файл без ведома Git. Механизм, которым пользуется Git при вычислении хеш-сумм, называется SHA-1 хеш. Это строка длиной в 40 шестнадцатеричных символов (0-9 и a-f), она вычисляется на основе содержимого файла или структуры каталога. SHA-1 хеш выглядит примерно так: 24b9da6552252987aa493b52f8696cd6d3b00373 Вы будете постоянно встречать хеши в Git, потому что он использует их повсеместно. На самом деле, Git сохраняет все объекты в свою базу данных не по имени, а по хеш-сумме содержимого объекта.
Когда вы производите какие-либо действия в Git, практически все из них только добавляют новые данные в базу Git. Очень сложно заставить систему удалить данные либо сделать что-то, что нельзя впоследствии отменить. Как и в любой другой СКВ, вы можете потерять или испортить свои изменения, пока они не зафиксированы, но после того, как вы зафиксируете снимок в Git, будет очень сложно что-либо потерять, особенно, если вы регулярно синхронизируете свою базу с другим репозиторием.
У Git есть три основных состояния, в которых могут находиться ваши файлы: изменён (modified), индексирован (staged) и зафиксирован (committed):
К изменённым относятся файлы, которые поменялись, но ещё не были зафиксированы.
• Индексированный — это изменённый файл в его текущей версии, отмеченный для
включения в следующий коммит.
• Зафиксированный значит, что файл уже сохранён в вашей локальной базе.
Мы подошли к трём основным секциям проекта Git: рабочая копия (working tree), область индексирования (staging area) и каталог Git (Git directory).
Рабочая копия является снимком одной версии проекта. Эти файлы извлекаются из сжатой базы данных в каталоге Git и помещаются на диск, для того чтобы их можно было использовать или редактировать. Область индексирования — это файл, обычно находящийся в каталоге Git, в нём содержится информация о том, что попадёт в следующий коммит. Её техническое название на языке Git — «индекс», но фраза «область индексирования» также работает. Каталог Git — это то место, где Git хранит метаданные и базу объектов вашего проекта. Это самая важная часть Git и это та часть, которая копируется при клонировании репозитория с другого компьютера.
параметры могут быть сохранены в трёх местах:
- Файл [path]/etc/gitconfig содержит значения, общие для всех пользователей системы и для всех их репозиториев. Если при запуске git config указать параметр --system, то параметры будут читаться и сохраняться именно в этот файл. Так как этот файл является системным, то вам потребуются права суперпользователя для внесения изменений в него.
- Файл ~/.gitconfig или ~/.config/git/config хранит настройки конкретного пользователя. Этот файл используется при указании параметра --global и применяется ко всем репозиториям, с которыми вы работаете в текущей системе.
- Файл config в каталоге Git (т. е. .git/config) репозитория, который вы используете в данный момент, хранит настройки конкретного репозитория. Вы можете заставить Git читать и писать в этот файл с помощью параметра --local, но на самом деле это значение по умолчанию. Неудивительно, что вам нужно находиться где-то в репозитории Git, чтобы эта опция работала правильно. Настройки на каждом следующем уровне подменяют настройки из предыдущих уровней, то есть значения в .git/config перекрывают соответствующие значения в [path]/etc/gitconfig.
Чтобы посмотреть все установленные настройки и узнать где именно они заданы, используйте команду
git config --list --show-origin
После установки Git — укажите ваше имя и адрес электронной почты. Это важно, потому что каждый коммит в Git содержит эту информацию, и она включена в коммиты, передаваемые вами, и не может быть далее изменена:
Открыть справку по любой команде можно так
$ git help <команда>
$ git <команда> --help $ man git-<команда>
$ man git-<команда>
2. Основы
Если у вас уже есть проект в каталоге, который не находится под версионным контролем Git, то команда git init
создаст в текущем каталоге новый подкаталог с именем .git, содержащий все необходимые файлы репозитория — структуру Git репозитория. На этом этапе ваш проект ещё не находится под версионным контролем. (добавляем файлы в индекс и коммитим)
Командой git clone
мы получим себе копию удаленного репозитория в которой будут почти все дынные из удаленного репозитория
Это важное отличие от других скв, например в svn для получения рабочей копиии репозитория используется checkout (только рабочая копия)
Таким образом в случае поломки сервера мы сможем восстановить его из любой копии репозитория (потеряются хуки, но слепки останутся)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
Статус Untracked означает, что Git видит файл, которого не было в предыдущем снимке состояния (коммите)
Для добавления файла в индекс используется - git add <filename>
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: README
Теперь файл проиндексирован, так как он находится в секции «Changes to be committed». Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add, будет добавлена в историю снимков состояния
git add
- Это многофункциональная команда, она используется для добавления под версионный контроль новых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния
Ситуация на скриншоте ниже наглядно демонстрирует, что Git индексирует файл в точности в том состоянии, в котором он находился, когда вы выполнили команду git add
Вы можете создать файл .gitignore. с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore:
$ cat .gitignore
*.[oa]
*~
Первая строка предписывает Git игнорировать любые файлы заканчивающиеся на «.o» или «.a» — объектные и архивные файлы, которые могут появиться во время сборки кода. Вторая строка предписывает игнорировать все файлы заканчивающиеся на тильду (~), которая используется во многих текстовых редакторах, например Emacs, для обозначения временных файлов
Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите. К шаблонам в файле .gitignore применяются следующие правила:
- Пустые строки, а также строки, начинающиеся с #, игнорируются
- Стандартные шаблоны являются глобальными и применяются рекурсивно для всего дерева каталогов
- Чтобы избежать рекурсии используйте символ слеш (/) в начале шаблона
- Чтобы исключить каталог добавьте слеш (/) в конец шаблона
- Можно инвертировать шаблон, использовав восклицательный знак (!) в качестве первого символа
Glob-шаблоны представляют собой упрощённые регулярные выражения, используемые командными интерпретаторами. Символ (*) соответствует 0 или более символам; последовательность [abc] — любому символу из указанных в скобках (в данном примере a, b или c); знак вопроса (?) соответствует одному символу; и квадратные скобки, в которые заключены символы, разделённые дефисом ([0-9]), соответствуют любому символу из интервала (в данном случае от 0 до 9). Вы также можете использовать две звёздочки, чтобы указать на вложенные каталоги: a/**/z соответствует a/z, a/b/z, a/b/c/z, и так далее
У github'a есть набор шаблонов для разных языков
https://github.com/github/gitignore
Они могут быть отправной точкой для файла .gitignore
в вашем проекте
git diff
- покажет разницу между текущим состоянием рабочего каталога и содержимым индексаgit diff --staged
- покажется разницу между последним коммитом и содержимым индекса (то есть то что войдет в коммит)
Через git difftool
можно просматривать диффы через другие утилиты (какие-то более удобные консольные или даже графические)
git commit
откроет редактор текста в котором будет предложено ввести commit-message, в нем уже будет вывод команды git status
Ключ -v
для git commit
кроме вывода git status
предварительно поместит в редактор текста еще и вывод git diff
Самой первой строкой будет пустая строка в которую и предлагается ввести свое описание коммита (git commit
&git diff
output в сам коммит не попадут, они просто позволяют сразу видеть что именно попадает в коммит чтобы можно было написать корректное описание)
Для того чтобы удалить файл из Git, вам необходимо удалить его из отслеживаемых файлов (точнее, удалить его из вашего индекса) а затем выполнить коммит. Это позволяет сделать команда git rm, которая также удаляет файл из вашего рабочего каталога, так что в следующий раз вы не увидите его как «неотслеживаемый»
Если вы изменили файл и уже проиндексировали его, вы должны использовать принудительное удаление с помощью параметра -f
. Это сделано для повышения безопасности, чтобы предотвратить ошибочное удаление данных, которые ещё не были записаны в снимок состояния и которые нельзя восстановить из Git
Чтобы удалить файл из индекса, оставив его при этом в рабочем каталоге, используйте опцию --cached
Команда
$ git mv README.md README
Эквивалентна командам
$ mv README.md README
$ git rm README.md
$ git add README
Полезный аргумент для git log
- -p
или --patch
, который показывает разницу (выводит патч), внесенную в каждый коммит
А если вы хотите увидеть сокращенную статистику для каждого коммита, вы можете использовать опцию --stat
Опция --pretty
принимает на вход oneline, short, medium, full, fuller, reference, email, raw, format и некоторые другие
Подробное описание форматов можно увидеть в секции PRETTY FORMATS
в git help log
format
принимает в себя строку из плейсхолдеров с помощью которой можно задать свой собственный формат
В примере ниже мы ищем коммиты которые затрагивают определенный файл и имеют в commit-message определенное слово
Если вы хотите переделать коммит — внесите необходимые изменения, добавьте их в индекс и сделайте коммит ещё раз, указав параметр --amend
:
$ git commit --amend
Эта команда использует область подготовки (индекс) для внесения правок в коммит. Если вы ничего не меняли с момента последнего коммита (например, команда запущена сразу после предыдущего коммита), то снимок состояния останется в точности таким же, а всё что вы сможете изменить — это ваше сообщение к коммиту
Очень важно понимать, что когда вы вносите правки в последний коммит, вы не столько исправляете его, сколько заменяете новым, который полностью его перезаписывает. В результате всё выглядит так, будто первоначальный коммит никогда не существовал, а так же он больше не появится в истории вашего репозитория
Очевидно, смысл изменения коммитов в добавлении незначительных правок в последние коммиты и, при этом, в избежании засорения истории сообщениями вида «Ой, забыл добавить файл» или «Исправление грамматической ошибки»
Пример убирания файла из индекса
Через git add *
мы добавили лишнего, и чтобы убрать из индекса что-либо, нужно сделать git status
и в его выводе будет подсказка о том как удалить файл из индекса
git checkout -- <file>
- позволяет откатить изменения в working tree
В примере ниже мы удаляем добавленный в индекс файл (то есть делаем изменения неотслеженные гитом, вместо удаления можно просто отредактировать файл) и командой checkout
убираем эти изменения
git remote
- покажет список доступных удаленных репозиториев (ключ -v
покажет и урлы)
vandud@macbook: zabbix [0] ? git remote
origin
vandud@macbook: zabbix [0] ? git remote -v
origin git@gitlab.i-free.com:puppet-modules/zabbix.git (fetch)
origin git@gitlab.i-free.com:puppet-modules/zabbix.git (push)
Чтобы добавить новый удаленный репозиторий - git remote add <shorname> <url>
git fetch
это как git pull
только другое
vandud@macbook: zabbix [0] ? git fetch origin
remote: Enumerating objects: 83, done.
remote: Counting objects: 100% (83/83), done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 83 (delta 36), reused 59 (delta 27)
Unpacking objects: 100% (83/83), 33.97 KiB | 644.00 KiB/s, done.
From gitlab.i-free.com:puppet-modules/zabbix
0439074..7007c2d master -> origin/master
При использовании pull, git пытается сделать всё за вас. Он сливает любые внесённые коммиты в ветку, в которой вы сейчас работаете. Команда pull автоматически сливает коммиты, не давая вам сначала просмотреть их. Если вы не пристально следите за ветками, выполнение этой команды может привести к частым конфликтам
При использовании fetch, git собирает все коммиты из целевой ветки, которых нет в текущей ветке, и сохраняет их в локальном репозитории. Однако он не сливает их в текущую ветку. Это особенно полезно, если вам нужно постоянно обновлять свой репозиторий, но вы работаете над функциональностью, неправильная реализация которой может негативно сказаться на проекте в целом. Чтобы слить коммиты в основную ветвь, нужно использовать merge
Грубо говоря, по дефолту git pull — это шоткод для последовательности двух команд: git fetch (получение изменений с сервера) и git merge (сливание в локальную копию)
Если хотите использовать поведение Git по умолчанию (простое смещение вперёд если возможно — иначе создание коммита слияния): git config --global pull.rebase "false"
Если хотите использовать перебазирование при получении изменений: git config --global pull.rebase "true"
git push <remote-name> <branch-name>
- Чтобы отправить вашу ветку master на сервер origin
git remote show <remote-name>
покажет информацию об удаленном репозитории
vandud@macbook: zabbix [0] ? git remote show origin
* remote origin
Fetch URL: git@gitlab.i-free.com:puppet-modules/zabbix.git
Push URL: git@gitlab.i-free.com:puppet-modules/zabbix.git
HEAD branch: master
Remote branches:
TSUPP-3966736 tracked
UPEADM-6749 tracked
master tracked
services_exludes tracked
test tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (local out of date)
Эта команда показывает какая именно локальная ветка будет отправлена на удалённый сервер по умолчанию при выполнении git push
Она также показывает, каких веток с удалённого сервера у вас ещё нет, какие ветки всё ещё есть у вас, но уже удалены на сервере
И для нескольких веток показано, какие удалённые ветки будут в них влиты при выполнении git pull
git remote rename <oldname> <newname>
позволяет переименовать удаленный репозиторийgit remote remove <remote-name>
удаляет
vandud@macbook: zabbix [0] ? git remote
origin
vandud-test-zabbix
vandud@macbook: zabbix [0] ? git remote rename vandud-test-zabbix vandud
vandud@macbook: zabbix [0] ? git remote
origin
vandud
vandud@macbook: zabbix [0] ? git remote remove vandud
vandud@macbook: zabbix [0] ? git remote
origin
git tag
Для отображение тегов. Чтобы фильтровать их согласно шаблону требуются параметры -l
или --list
Git использует два основных типа тегов: легковесные и аннотированные
Легковесный тег — это что-то очень похожее на ветку, которая не изменяется — просто указатель на определённый коммит
А вот аннотированные теги хранятся в базе данных Git как полноценные объекты. Они имеют контрольную сумму, содержат имя автора, его e-mail и дату создания, имеют комментарий и могут быть подписаны и проверены с помощью GNU Privacy Guard (GPG)
Ключ -a
создает аннотированный тэг - git tag -a v1.4 -m "my version 1.4"
git tag
без ничего создает легковесный - git tag v1.4-lw
Чтобы повесить тэг на какой-то старый коммит нужно просто указать его хэш
Было:
Вешаем тэг
git tag 0.0 02800787767b7e55f9f741f65503e67727fbe5a5
Стало:
Как видно появился тэг на первом коммите
По умолчанию, команда git push не отправляет теги на удалённые сервера. После создания теги нужно отправлять явно на удалённый сервер. Процесс аналогичен отправке веток — достаточно выполнить команду git push origin <tagname>
Можно отправлять тэги по одиночке, а можно добавить опцию --tags
и отправятся все сразу
Чтобы удалить тэг у себя локально - git tag -d <tagname>
Но с сервера он так не удалится
vandud@macbook: gittest [0] ? git tag | cat
0.0
0.1
vandud@macbook: gittest [0] ? git tag -d 0.0
Deleted tag '0.0' (was 0280078)
vandud@macbook: gittest [0] ? git tag | cat
0.1
Для удаления тэга в удаленном репозитории есть два путя:
vandud@macbook: gittest [0] ? git push origin --delete 0.1
remote: . Processing 1 references
remote: Processed 1 references in total
To https://gitea.vandud.ru/vandud/test1.git
- [deleted] 0.1
vandud@macbook: gittest [0] ? git push origin :refs/tags/0.1-lw
remote: . Processing 1 references
remote: Processed 1 references in total
To https://gitea.vandud.ru/vandud/test1.git
- [deleted] 0.1-lw
Для перехода к тэгу - git checkout v2.0.0
Но репозиторий переходит в detached HEAD state, а это опасно
Если необходимо делать изменения в старой версии, то нужно делать отдельную ветку
git checkout -b version2 v2.0.0
Можно задавать алиасы в рамках гита
vandud@macbook: gittest [0] ? git config --global alias.last 'log -1 HEAD'
vandud@macbook: gittest [0] ? git last
commit 3479140973a4c5b53b20fb0a5b0fa5beef54c012
Author: Ivan Dudin <s@vandud.ru>
Date: Sun Jan 2 05:55:21 2022 +0300
commit for lightweight tag
Если вы захотите выполнить внешнюю команду, а не подкоманду Git, то следует начать команду с символа !
. Продемонстрируем этот случай на примере создания псевдонима git visual для запуска gitk:
$ git config --global alias.visual '!gitk'
Вопросы
- Где хранится контент файлов добавленных в индекс?
- Что по владению ветками? Если у меня на репу девелоперские права, то я не могу пушить в мастер но могу создавать самодельные ветки, а также могу коммитить и пушить в чужие самодельные ветки. Каким образом происходит разделение куда я могу пушить, а куда нет?
3. Ветвление в Git
aoeu
git status -s
Команда git status
имеет ключ -s/--short
который делает вывод короче
Пути до файлов в выводе этой команды, в отличие от многих других команд git, относительны
vandud@macbook: testdir [0] ? git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: testfile3
new file: ../testfile
Пути до файлов в выводе отображаются относительно текущей директории
Короткий формат имеет две разновидности
XY PATH
XY ORIG_PATH -> PATH
ORIG_PATH - откуда был скопирован/переименован файл
XY - двухбуквенный статус-код
Двухбуквенный статус имеет три разновидности:
-
Когда мердж был успешным или мерджа не было, X показывает статус индекса, а Y показывает статус рабочего дерева
X Y Meaning [AMD] not updated M [ MD] updated in index A [ MD] added to index D deleted from index R [ MD] renamed in index C [ MD] copied in index [MARC] index and work tree matches [ MARC] M work tree changed since index [ MARC] D deleted in work tree [ D] R renamed in work tree [ D] C copied in work tree -
При конфликте слияния эти две буквы показывают состояние каждой головы (head) слияния
X Y Meaning D D unmerged, both deleted A U unmerged, added by us U D unmerged, deleted by them U A unmerged, added by them D U unmerged, deleted by us A A unmerged, both added U U unmerged, both modified -
Обе буквы одинаковы:
- Для неотслеживаемых файлов (untracked) -
??
- Для игнорируемых через gitignore файлов -
!!
X Y Meaning ? ? untracked ! ! ignored - Для неотслеживаемых файлов (untracked) -
-
' '
- unmodified -
M
- modified -
A
- added -
D
- deleted -
R
- renamed -
C
- copied -
U
- updated but unmerged
Index File
https://github.com/git/git/blob/master/Documentation/technical/index-format.txt
Самих данных в индексе нет(
Надо разбираться и дописывать
Не догоняю где хранится контент файлов после команды git add
Tips
Change origin
git remote remove origin
git remote add origin git@git.i-free.com:monitoring/infrastructure.git
git pull origin master
Switch from master
to main
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main