Когда-то в моем проекте был файл, который я бы хотел получить.
Проблема: я понятия не имею, когда я удалил это и по какому пути это было.
Как я могу найти коммиты этого файла, когда он существовал?
Когда-то в моем проекте был файл, который я бы хотел получить.
Проблема: я понятия не имею, когда я удалил это и по какому пути это было.
Как я могу найти коммиты этого файла, когда он существовал?
Ответы:
Если вы не знаете точный путь, который вы можете использовать
git log --all --full-history -- "**/thefile.*"
Если вы знаете путь к файлу, вы можете сделать это:
git log --all --full-history -- <path-to-file>
Это должно показать список коммитов во всех ветвях, которые касались этого файла. Затем вы можете найти версию файла, который вы хотите, и отобразить его с ...
git show <SHA> -- <path-to-file>
Или восстановите его в рабочую копию с помощью:
git checkout <SHA>^ -- <path-to-file>
Обратите внимание на символ вставки ( ^
), который получает извлечение до идентифицированного, потому что в момент <SHA>
фиксации файл удаляется, нам нужно посмотреть предыдущий коммит, чтобы получить содержимое удаленного файла.
git log -- <path>
будет выводить, когда вы находитесь на ветке, в которой файл никогда не существовал. Вы должны всегда использовать git log --all -- <path>
, чтобы убедиться, что вы не пропустите изменения, которые произошли в других ветках. Команда git log -- <path>
может быть очень опасной, если у вас более одной ветви и вы склонны забывать пути и ветви (как я), а также опасно, если вы работаете с другими разработчиками.
git checkout <SHA>^ -- <path-to-file>
(обратите внимание на символ ^), потому что в момент фиксации <SHA> файл удаляется, нам нужно посмотреть предыдущий коммит, чтобы получить содержимое удаленного файла
Получить список удаленных файлов и скопировать полный путь к удаленному файлу
git log --diff-filter=D --summary | grep delete
Выполните следующую команду, чтобы найти идентификатор фиксации этого коммита и скопировать идентификатор коммита
git log --all -- FILEPATH
Показать разницу удаленного файла
git show COMMIT_ID -- FILE_PATH
Помните, что вы можете записать вывод в файл, используя >
как
git show COMMIT_ID -- FILE_PATH > deleted.diff
unknown revision or path not in the working tree
.
git log --diff-filter=D --summary | grep -E 'delete|^commit\s+\S+'
git-grep-latest(){ result_path=$(git log --diff-filter=D --summary | grep $1 | head -1 | awk '{print $4;}'); latest_commit=$(git log --all -- $result_path | head -1 | awk '{print $2;}'); git show $latest_commit -- $result_path; }
и теперь вы можете просто сделать:git-grep-latest some_text
linux pipes
... вам понравится.
Не удалось изменить принятый ответ, поэтому добавьте его в качестве ответа здесь,
чтобы восстановить файл в git, используйте следующее (обратите внимание на знак '^' сразу после SHA)
git checkout <SHA>^ -- /path/to/file
<SHA>~1
должно работать так же, без необходимости заключать его в кавычки.
Предположим, вы хотите восстановить файл с именем MyFile
, но не знаете его путь (или его расширение):
Prelim .: Избегайте путаницы, перейдя к корню git
Нетривиальный проект может иметь несколько каталогов с одинаковыми или одинаковыми именами.
> cd <project-root>
Найди полный путь
git log --diff-filter = D --summary | grep удалить | grep MyFile
delete mode 100644 full/path/to/MyFile.js
full/path/to/MyFile.js
путь и файл, который вы ищете.
Определите все коммиты, которые повлияли на этот файл
git log --oneline --follow - полный / путь / к / MyFile.js
bd8374c Some helpful commit message
ba8d20e Another prior commit message affecting that file
cfea812 The first message for a commit in which that file appeared.
Оформить заказ
Если вы выберете первый в списке коммит (последний в хронологическом порядке, здесь bd8374c), файл не будет найден, так как он был удален в этом коммите.
> git checkout bd8374c -- full/path/to/MyFile.js
`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`
Просто выберите предыдущий (добавить каретку) коммит:
> git checkout bd8374c^ -- full/path/to/MyFile.js
git log --diff-filter=D --summary | find "delete" | find "MyFile"
И шаг 3 , обратите внимание на кавычки вокруг хеша:git checkout "bd8374c^" -- full/path/to/MyFile.js
@ Янтарь дал правильный ответ! Еще одно дополнение, если вы не знаете точный путь к файлу, вы можете использовать подстановочные знаки! Это сработало для меня.
git log --all -- **/thefile.*
Ниже приведена простая команда, в которой пользователь dev или git может передать имя удаленного файла из корневого каталога репозитория и получить историю:
git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all --
Если кто-нибудь, может улучшить команду, пожалуйста, сделайте.
Попробуйте использовать одно из средств просмотра, например, gitk
чтобы вы могли просмотреть историю, чтобы найти этот наполовину запомненный файл. (используйте gitk --all
при необходимости для всех филиалов)
--all
вариант важен как для вашего ответа, так и для принятого ответа.
Резюме:
Вы ищете полный путь к файлу в истории удаленных файлов. git log --diff-filter=D --summary | grep filename
Вы восстанавливаете свой файл из коммита до того, как он был удален
restore () {
filepath="$@"
last_commit=$(git log --all --full-history -- $filepath | grep commit | head -1 | awk '{print $2; exit}')
echo "Restoring file from commit before $last_commit"
git checkout $last_commit^ -- $filepath
}
restore my/file_path
Вот мое решение:
git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>
git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>