Как да си върна изтрития и ангажиран файл в git repo?

Имам проект на git. Моят проект има файлове като:

file1.js
file2.html
file3.js
file4.css
file5.html
file6.jpg
file7.html
file8.js
file9.css

Направих git -rm име на файл за всички файлове и ги ангажирах, докато не ми остана

file1.js
file2.html

Трябва да си върна файла 6.jpg

Как да получа file6.jpg, така че моето репо ще има

file1.js
file2.html
file6.jpg

person Mike    schedule 05.04.2013    source източник
comment
направихте ли един ангажимент за всички изтривания?   -  person niculare    schedule 05.04.2013
comment
след това направете проверка при ангажирането, преди да сте изтрили file6.jpg и премахнете другите файлове с изключение на 1, 2 и 6   -  person niculare    schedule 05.04.2013


Отговори (4)


git checkout HEAD~N -- file6.jpg

Където N е броят на ангажиментите назад във времето, където file6.jpg е присъствал.

person Gabriele Petronella    schedule 05.04.2013
comment
Мисля, че това има смисъл, изглежда, че си върнах файла, но той няма да се появи на github.com. Също така направих git push origin master - person Mike; 05.04.2013
comment
трябва да го ангажирате след плащане, преди да натиснете - person Gabriele Petronella; 05.04.2013
comment
Благодаря. Това проработи. Ако щях да изтрия всички файлове в един комит. Каква е алтернативата в такъв случай? - person Mike; 06.04.2013
comment
Можете или да поставите HEAD~1, за да се върнете назад от един комит, или HEAD^, което е синоним. - person Gabriele Petronella; 06.04.2013

git checkout може да е най-простата опция за един файл.

  1. Използвайте git log, за да видите хронологията на ангажиментите си. Намерете хеша на ангажимента преди да премахнете въпросния файл. Например:

    commit 5faff7e3f74c3408985acecd1dbb90feeb7b1d75 <--- "hash"
    Author: Nick Tomlin <[email protected]>
    Date:   Fri Apr 5 11:34:03 2013 -0500
    
  2. след това изпълнете git checkout <hash> path/to/file6.jpg, като замените <hash> с низа от знаци по-горе (обикновено се нуждаете само от последните 5 или нещо такова, но нека просто ги използваме всички сега, за да сме сигурни. Ако сте в директорията, която се намира file6.jpg, можете просто да направите git checkout <hash> file6.jpg

Това е по-дълъг подход за достъп до ангажимент, може просто да се използва HEAD~6, но обикновено го предпочитам, когато препращам към комити, които са по-назад от HEAD~3. По-лесно е да се посочи грешният комит, като се използва относителната препратка ~ и в крайна сметка преглеждам дневника си, за да разбера точно кой комит ми е необходим така или иначе :).

person Nick Tomlin    schedule 05.04.2013
comment
как да намеря хеш. съжалявам, нов съм в git. - person Mike; 05.04.2013
comment
Благодаря, това проработи, но подходът на Габриеле също проработи. Знаете ли каква е разликата между двата подхода? Ако щях да изтрия и ангажирах всички файлове в един кратък. какъв е начинът да си върна желания файл. - person Mike; 06.04.2013
comment

Има API функция на Oracle DB, която очаква като вход низ, представляващ дата (или в други случаи число), който е форматиран от предоставената маска за формат.

Преди да отида и внедря анализатора на Oracle Format Mask, реших да попитам дали има вграден .net или начин от трета страна за конвертиране на DateTime .net обект в string с помощта на Oracle Format Mask?

Актуализиране

Примери:

DateTime date = DateTime.Now;
string convertedDate = ConvertDateTimeToOracleFormattedString (date, "Month DD, YYYY"); // should produce: March 21, 2014
convertedDate = ConvertDateTimeToOracleFormattedString (date, "CC BC"); // should produce: 21
// any other valid oracle format combination: http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34924 

Текущата ми идея е да анализирам предоставената Oracle Format Mask в еквивалентен .net персонализиран низ за формат на дата и час: http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx и го използвайте, когато конвертирате .net DateTime в низ: DateTime.Now.ToString ("equivalentDotNetFormat");. Еквивалентният .net формат на „ДД месец, ГГГГ“ ще бъде „ММММ дд, гггг“. Освен ако няма по-бърз подход.

- person Nick Tomlin; 06.04.2013

git checkout $(git log -1 --pretty='%h' -- <path>)^ -- <path>

Повреда

Използване на git log за намиране на последния комит, засягащ желания файл

$(git log -1 --pretty='%h' -- <path>)

  • Изпълнява командата git log с помощта на форматиране --pretty, което показва само хеша.
  • Използва разделителя -- за изрично указване на файл, а не препратка към къмит.
  • Следвано от пътя и името на файла, който искаме да извлечем.
  • Опаковахме всичко това в $(), за да можем да го вградим в друга git команда като променлива.
  • Това ще върне ангажимента, в който е премахнат дадения файл.

Това, разбира се, може да се използва самостоятелно без $(), ако просто искате да знаете кога този файл е бил премахнат - промяната или премахването на красивото форматиране ще ви даде повече информация за намерения ангажимент.

Използване на git checkout за извличане на файл във вида, в който е бил в даден комит

git checkout <ref>^ -- <path>

  • Изпълнява git checkout с помощта на ангажимент и указване на път.
  • Когато е указан път, git просто пресъздава състоянието на този път при предоставената препратка.
  • Добавяйки морков ^ към препратката, ние всъщност сочим към непосредствения предшественик.
  • Искаме непосредствения предшественик, защото къмитът, който получаваме от журнала, няма да съдържа файла - тъй като това е комитът, в който файлът е изтрит.

Съберете всичко заедно и проверявате файла в състоянието, в което е бил при комита точно преди този файл да бъде премахнат. Ако стартирате това на файл, който не е премахнат, то просто ще отмени каквато и да е промяна, която е направена най-скоро на този файл.

Псевдоним

git config --global alias.unrm '!COMMIT=$(git log -1 --pretty='%h' -- "$1"); git checkout $COMMIT^ -- "$1"'

Създадох псевдоним от това, наречен unrm, като un-remove. Ако изпълните горната команда, от този момент нататък просто ще трябва да изпълните..

git unrm <path>

Редактиране: Добавих обратна връзка към командата.

git config --global alias.unrm '!COMMIT=$(git log -1 --pretty='%h' -- "$1"); git checkout $COMMIT^ -- "$1"; echo "File: $1, was restored from commit $COMMIT"; git show -s $COMMIT'

Сега той ви информира какво е направил и ви показва къмита, от който е възстановил файла.

person eddiemoya    schedule 06.04.2013

Ако приемем, че file6.jpg е бил ангажиран преди това, можете да получите всички ревизии на file6.jpg във вашето git хранилище чрез:

git rev-list --objects --all | grep file6.jpg

След това можете да възстановите файла с помощта на

git cat-file {sha} > file6.jpg

Добавете файла и го ангажирайте.

Вижте също този отговор, който говори за това как да получите всички обекти от git хранилище: https://stackoverflow.com/a/7350019

и този сайт за вътрешността на git обект: http://git-scm.com/book/en/Git-Internals-Git-Objects

person Charlie    schedule 05.04.2013
comment
това наистина е най-сложният начин, който някога съм виждал за толкова проста задача. - person Gabriele Petronella; 06.04.2013