Разница между «git add -A» и «git add».

2918

Команда git add [--all|-A]кажется идентичной git add .. Это правильно? Если нет, чем они отличаются?

cmcginty
источник

Ответы:

4242

Этот ответ относится только к Git версии 1.x . Для Git версии 2.x см. Другие ответы.


Резюме:

  • git add -Aэтапы все изменения

  • git add .вносит новые файлы и модификации без удаления

  • git add -uэтапы модификации и удаления, без новых файлов


Деталь:

git add -Aэквивалентно git add .; git add -u.

Важным моментом git add .является то, что он смотрит на рабочее дерево и добавляет все эти пути к поэтапным изменениям, если они либо изменены, либо являются новыми и не игнорируются, он не выполняет никаких действий «rm».

git add -uпросматривает все уже отслеженные файлы и вносит изменения в эти файлы, если они отличаются или они были удалены. Он не добавляет никаких новых файлов, он только вносит изменения в уже отслеженные файлы.

git add -A это удобный способ сделать это.

Вы можете проверить различия с помощью чего-то вроде этого (обратите внимание, что для Git версии 2.x ваш вывод git add . git status будет другим):

git init
echo Change me > change-me
echo Delete me > delete-me
git add change-me delete-me
git commit -m initial

echo OK >> change-me
rm delete-me
echo Add me > add-me

git status
# Changed but not updated:
#   modified:   change-me
#   deleted:    delete-me
# Untracked files:
#   add-me

git add .
git status

# Changes to be committed:
#   new file:   add-me
#   modified:   change-me
# Changed but not updated:
#   deleted:    delete-me

git reset

git add -u
git status

# Changes to be committed:
#   modified:   change-me
#   deleted:    delete-me
# Untracked files:
#   add-me

git reset

git add -A
git status

# Changes to be committed:
#   new file:   add-me
#   modified:   change-me
#   deleted:    delete-me
CB Bailey
источник
41
Как насчет разницы между git add *?
Джаред
3
слишком плохо git add -A -pне работает, как и следовало ожидать (спросите в интерактивном режиме о неотслеживаемых файлах)
Эрик Каплун,
2
Пожалуйста, обновите ответ. Это должно быть: git add -A :/илиgit add -A .
Габриэль Ламас
5
Для информации, в более новых версиях git git add -uстало git add -u :/с последним параметром, являющимся путем, позволяя вам -u определенные каталоги, :/обрабатывает все дерево.
Бризи
15
@CharlesBailey, Git действительно любит усложнять вещи без веской причины. Существует ли реальный вариант использования, при котором кому-то конкретно понадобится git add -uили, git add .благодаря этому, он облегчит свою жизнь даже после учета добавленного дополнительного ментального налога, чтобы гарантировать отсутствие проблем с синхронизацией? Интересно, почему Git не разбивается add -uна две отдельные команды, add -u1и add-u2одна из них работает с файлами, начинающимися с цифр, а другая - с файлами, начинающимися с цифр,
Pacerier,
946

Вот таблица для быстрого понимания:

Git Version 1.x :

Введите описание изображения здесь

Git Version 2.x :

Введите описание изображения здесь

Длинные флаги:

  • git add -A эквивалентно git add --all
  • git add -u эквивалентно git add --update

Дальнейшее чтение:

разработчик
источник
1
Спасибо за стол. Есть ли способ добавить только файлы, которые были изменены. Нет новых файлов или удаленных файлов
Gokul NK
3
@Gokul: Согласно этому посту , вы можете использовать git diff-files -z --diff-filter=M --name-only | xargs -0 git addдля добавления только измененные файлы, но не новые файлы или удаления.
Вилле
93
Это не совсем верно, так как git add .добавляет только новые файлы, которые находятся на текущем пути. Т.е. если у вас есть новый каталог ../foo, его git add -Aбудет ставить, git add .не будет.
Майло Велондек,
2
Итак, git add .эквивалентно git add -A ., что эквивалентноgit add "*"
flow2k
Я все еще не понимаю, как добавить git "*". Не могли бы вы рассказать об этом немного подробнее?
HS Umer farooq
176

С Git 2.0 git add -Aпо умолчанию: git add .равноgit add -A . .

git add <path>то же самое, что " git add -A <path>" сейчас, так что " git add dir/" заметит пути, которые вы удалили из каталога, и запишет удаление.
В более старых версиях Git « git add <path>» игнорировал удаления.

Вы можете сказать « git add --ignore-removal <path>», чтобы добавить только добавленные или измененные пути <path>, если вы действительно этого хотите.

git add -Aэто как git add :/( добавить все из верхней папки git repo ).
Обратите внимание, что git 2.7 (ноябрь 2015) позволит вам добавить папку с именем " :"!
См. Коммит 29abb33 (25 октября 2015 г.) от Junio ​​C Hamano ( gitster) .


Обратите внимание, что начиная git 2.0 (Q1 или Q2 2014) , когда речь идет о git add .(текущем пути в рабочем дереве), вы также должны использовать ' .' в других git addкомандах.

Это значит:

" git add -A ." эквивалентно " git add .; git add -u ."

(Обратите внимание на дополнительные ' .' для git add -Aиgit add -u )

Потому что git add -Aили git add -uбудет работать (начиная только с git 2.0) на всем рабочем дереве , а не только на текущем пути.

Эти команды будут работать со всем деревом в Git 2.0 для согласованности с " git commit -a" и другими командами . Поскольку не будет никакого механизма, заставляющего « git add -uвести себя так, как если бы» git add -u ., важно, чтобы те, кто привык « git add -u» (без указания пути), обновляли индекс только для путей в текущем подкаталоге, чтобы начать тренировать свои пальцы, чтобы явно сказать « git add -u .«когда они имеют в виду это до Git 2.0.

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

VonC
источник
3
@NickVolynkin Это здорово! Рад видеть, что международное сообщество SO работает так, как задумано. Для справки: ru.stackoverflow.com/a/431840
VonC
@VonC, Ницца, у ребят из Git действительно была щека, чтобы сказать, что их обновление «сделает вещи более последовательными». То, что они сделали, создало больше путаницы и несоответствий. Там 26 алфавитов, и им пришлось повторно использовать флаг, который уже использовался.
Pacerier
136

Из инструкций Чарльза , после проверки мое предлагаемое понимание будет следующим:

# For the next commit
$ git add .   # Add only files created/modified to the index and not those deleted
$ git add -u  # Add only files deleted/modified to the index and not those created
$ git add -A  # Do both operations at once, add to all files to the index

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

Ричард
источник
6
это больше не верно в 2.0. Добавить . равно -A для того же пути, разница только в том случае, если в других путях дерева есть новые файлы
Claudiu Creanga
41

С Git 2.0 все изменилось ( 2014-05-28 ):

  • -A теперь по умолчанию
  • Старое поведение теперь доступно с --ignore-removal .
  • git add -uи git add -Aв подкаталоге без путей в командной строке работают по всему дереву.

Так что для Git 2 ответ таков:

  • git add . а также git add -A . добавьте новые / измененные / удаленные файлы в текущий каталог
  • git add --ignore-removal . добавляет новые / измененные файлы в текущий каталог
  • git add -u . добавляет измененные / удаленные файлы в текущий каталог
  • Без точки добавьте все файлы в проект независимо от текущего каталога.
0xF
источник
4
Я не думаю, что это правильно. При использовании git v2.10.windows.2 «git add» возвращает «Ничего не указано, ничего не добавлено». 'git add -A' добавляет все измененные файлы. Что говорит о том, что «-А» не используется по умолчанию.
Нейтрино
34

Более дистиллированный быстрый ответ:

Делает оба ниже (так же, как git add --all )

git add -A

Этапы новые + измененные файлы

git add .

Этапы изменены + удаленные файлы

git add -u
К. Килиан Линдберг
источник
5
Здравствуйте, а что если вы просто хотели разместить только измененные файлы? Как бы Вы это сделали?
TheGrapeBeyond
2
Здравствуйте, хорошо, хороший вопрос. Насколько мне известно, не существует простого флага для этого .. git diff-files -z --diff-filter = M --name-only | xargs -0 git add from -> stackoverflow.com/questions/14368093/…
К. Килиан Линдберг
2
На самом деле это git add :/+git add -u :/
Ник Волынкин
27

В Git 2.x :

  • Если вы находитесь прямо в рабочем каталоге , то git add -Aи git add .работайте без разницы.

  • Если вы находитесь в каком-либо подкаталоге рабочего каталога , git add -Aвы добавите все файлы из всего рабочего каталога и git add .добавите файлы из вашего текущего каталога .

И это все.

simhumileco
источник
12

Я надеюсь, что это может добавить больше ясности.

!The syntax is
git add <limiters> <pathspec>
! Aka
git add (nil/-u/-A) (nil/./pathspec)

Ограничителями могут быть -u или -A или ноль.

Pathspec может быть путем к файлу или точкой, '.' указать текущий каталог.

Важные знания о том, как Git «добавляет»:

  • Невидимые файлы с префиксом точки (файлы точек) никогда не распознаются Git автоматически. Они даже не указаны как «неотслеживаемые».
  • Пустые папки никогда не добавляются Git. Они даже не указаны как «неотслеживаемые». (Обходной путь - добавить пустой файл, возможно, невидимый, к отслеживаемым файлам.)
  • Состояние Git не будет отображать информацию о подпапках, то есть неотслеживаемых файлах, если не отслежен хотя бы один файл в этой подпапке. До этого Git считает всю папку вне области видимости а-ля "пустая". В нем нет отслеживаемых предметов.
  • Указание filespec = '.' (точка) или текущий каталог не является рекурсивным, если -Aне указано иное. Dot относится исключительно к текущему каталогу - он пропускает пути, найденные выше и ниже.

Теперь, учитывая это знание, мы можем применить ответы выше.

Ограничители заключаются в следующем.

  • -u= --update= подмножество отслеживаемых файлов => Добавить = Нет; Изменить = Да; Удалить = Да. => если предмет отслеживается.
  • -A= --all(нет такого -a, что дает синтаксическую ошибку) = надмножество всех неотслеживаемых / отслеживаемых файлов, за исключением случаев, когда в Git до 2.0, где, если задана точечная спецификация файла, учитывается только эта конкретная папка. => если элемент распознан, git add -Aнайдет его и добавит.

Pathspec выглядит следующим образом.

  • В Git до 2.0 для двух ограничителей (update и all) новым значением по умолчанию является работа со всем рабочим деревом вместо текущего пути (Git 1.9 или более ранней),
  • Однако в версии 2.0 операция может быть ограничена текущим путем: просто добавьте явный суффикс точки (который также действителен в Git 1.9 или более ранней версии);

git add -A .

git add -u .

В заключение, моя политика:

  1. Убедитесь, что любые фрагменты / файлы, которые будут добавлены, учитываются в git status .
  2. Если какие-либо элементы отсутствуют, из-за невидимых файлов / папок добавьте их отдельно.
  3. Хорошего .gitignore файл, чтобы обычно только интересующие его файлы не отслеживались и / или не распознавались.
  4. На верхнем уровне хранилища «git add -A» добавит все элементы. Это работает во всех версиях Git.
  5. Удалите все нужные элементы из индекса, если это необходимо.
  6. Если есть большая ошибка, выполните git reset, чтобы полностью очистить индекс.
AnneTheAgile
источник
12

git add .equals git add -A .добавляет файлы в индекс только из текущей и дочерней папок.

git add -A добавляет файлы для индексации из всех папок в рабочем дереве.

PS: информация относится к Git 2.0 (2014-05-28).

Alex78191
источник
9

Оба git add .и git add -Aбудут помещать все новые, измененные и удаленные файлы в более новые версии Git.

Разница в том, что git add -Aфайлы в «верхнем, текущем и подкаталогах» помещаются в ваш рабочий Git-репозиторий. Но делать git add .только этапы файлов в текущем каталоге и подкаталогах, следующих за ним ( не файлы, лежащие снаружи, т. Е. Более высокие каталоги).

Вот пример:

/my-repo
  .git/
  subfolder/
    nested-file.txt
  rootfile.txt

Если текущим рабочим каталогом является /my-repo, и вы делаете rm rootfile.txt, а затем cd subfolder, затем git add ., он не будет размещать удаленный файл. Но выполнение git add -A, безусловно, внесет это изменение независимо от того, откуда вы выполняете команду.

sbr_amd
источник
3

-AОпция добавляет, изменяет и удаляет запись индекса для соответствия рабочего дерева.

В Git 2 эта -Aопция теперь используется по умолчанию.

Когда .добавляется a, который ограничивает область обновления до каталога, в котором вы находитесь в настоящее время, согласно документации Git

Если не задано no <pathspec>при использовании опции -A, обновляются все файлы во всем рабочем дереве (старые версии Git использовались для ограничения обновления текущим каталогом и его подкаталогами).

Одна вещь, которую я хотел бы добавить, это то, что если используется режим --interactiveили -p, то он git addбудет вести себя так, как если бы использовался -uфлаг update ( ), а не добавлять новые файлы.

Иегуда Шварц
источник