Нужно ли создавать новую ветку для того, чтобы набрать sh определенный файл, если я хочу избежать отправки всех моих других файлов? - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть несколько файлов в моем локальном компьютере, в которых я хочу только добавить pu sh определенный файл в свой github, но каждый раз, когда я добавляю и фиксирую этот конкретный файл, даже если я делаю pu sh в свой github ; все файлы передаются на него вместо того, чтобы только нажимать тот единственный файл, который я хочу быть единственным, переданным этому github. Поэтому мне интересно, возможно, мне придется создать другую ветвь, отличную от моей основной ветки, так как кажется, что независимо от того, что все мои попытки pu sh будут передавать все мои файлы вместо конкретного. Где-то я читал, что github передает только те файлы, которые вы добавили в последний раз, но это не так для меня, потому что, когда я добавляю и фиксирую файл, когда я sh выталкиваю все файлы, они не редактируются. Так как же сделать sh этот единственный файл?

1 Ответ

1 голос
/ 10 апреля 2020

Git никогда толкает файлы. Git только толкает коммитов .

Каждый коммит содержит каждый файл или, точнее, каждый файл, который идет с этим коммитом, как снимок.

Например, предположим, у вас есть небольшой репозиторий с тремя коммитами:

$ git init
Initialized empty Git repository in ...
$ echo example > README.md
$ git add README.md
$ git commit -m initial
[master (root-commit) 1ba91cb] initial
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ echo contents for file1 > file1.txt; git add file1.txt
$ echo contents for file2 > file2.txt; git add file2.txt
$ git commit -m commit-2
[master a232778] commit-2
 2 files changed, 2 insertions(+)
 create mode 100644 file1.txt
 create mode 100644 file2.txt
$ echo different content > file1.txt; git add file1.txt
$ git commit -m commit-3
[master b6b2eee] commit-3
 1 file changed, 1 insertion(+), 1 deletion(-)

Давайте посмотрим имена и информацию о файлах внутри commit-3:

$ git ls-tree -r HEAD
100644 blob 33a9488b167e4391ad6297a1e43e56f7ec8a294e    README.md
100644 blob 802d4bbd2e8eae48bbaab3b2bb65d5b7396a374a    file1.txt
100644 blob 43a59a7b12bfe183338873ba47312d0840488539    file2.txt

Мы только изменили один файл в этом третьем коммите, но все три файла находятся в нем. Как насчет имен и информации о файлах в начальном коммите?

$ git ls-tree -r HEAD~2
100644 blob 33a9488b167e4391ad6297a1e43e56f7ec8a294e    README.md

Итак, это совершенно нормально: каждый коммит имеет все файлы этого коммита. Это всегда то, что вы хотите!

Где-то я читал, что github выдвигает только те файлы, которые вы добавили в последнее время ...

Здесь скрывается совершенно иная концепция , В то время как git push толкает коммитов , каждый коммит состоит из нескольких объектов . Давайте подробнее рассмотрим третий коммит:

$ git cat-file -p HEAD | sed 's/@/ /'
tree 9a5b053002b6113f670344f397042dcf1b04ea68
parent a2327788f785cda09275bcbb02bf57121dc537ca
author Chris Torek <chris.torek gmail.com> 1586474456 -0700
committer Chris Torek <chris.torek gmail.com> 1586474456 -0700

commit-3

Обратите внимание, что сам коммит объект сам состоит из строк tree, parent, author, committer , пустая строка и текст сообщения о фиксации.

Объект tree - это то, что мы видим в выводе git ls-tree:

$ git cat-file -p HEAD^{tree}
100644 blob 33a9488b167e4391ad6297a1e43e56f7ec8a294e    README.md
100644 blob 802d4bbd2e8eae48bbaab3b2bb65d5b7396a374a    file1.txt
100644 blob 43a59a7b12bfe183338873ba47312d0840488539    file2.txt

Этот объект дерева относится до трех объектов BLOB-объектов . Копия README.md в этом древовидном объекте в точности совпадает с копией в дереве первого коммита:

$ git cat-file -p 33a9488b167e4391ad6297a1e43e56f7ec8a294e
example

Когда вы вызываете git push, Git на самом деле упаковывает объекты для отправки коммитов. Этот пакет обычно принимает форму того, что Git называет тонкой упаковкой . Тонкий пакет использует информацию о том, какие коммиты они уже имеют , и, следовательно, какие объекты дерева и блобов они должны иметь.

Предположим, что у них уже есть первые два коммита. Ваш Git вызовет их Git и предложит коммит # 3. Они скажут: Хорошо, мне нужен этот коммит. Ваш Git также немедленно предложит коммит # 2, как это требуется здесь, но для этого они скажут: Нет, спасибо У меня есть это и все его предки. Итак, ваш Git теперь знает, что у них есть начальный и средний коммит, и это только последний, который им нужен.

Следовательно, когда вы запускаете git push origin master, ваши Git не будут отправлять объекты 33a9488b167e4391ad6297a1e43e56f7ec8a294e и 43a59a7b12bfe183338873ba47312d0840488539. У Git в origin уже есть они. Таким образом, ваш Git отправляет тонкий пакет, содержащий последний объект коммита, его последнее дерево - у них нет этого объекта - и объект для одного обновленного файла, который в данном случае является объектом с ha sh ID 802d4bbd2e8eae48bbaab3b2bb65d5b7396a374a. Тонкая упаковка не содержит двух других объектов BLOB-объектов; они уже есть.

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

Здесь вам ничего не нужно делать. Просто запустите git push; Git заботится о том, чтобы выяснить, какие Git объекты требуются. Делайте обычные коммиты обычным способом, и Git выполнит работу Git.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...