[Useful Info] Git - Местене на файлове, запазвайки историята им
Здравейте!
Доста време се лутах и чудех как да обединя repository-тата в GitHub акаунта си без да изгубя историята на всички къмити. Информацията, която намирах в повечето случаи беше доста обща и/или объркваща, затова искам да споделя един мини-туториал с това как най-накрая успях да осъществя тази луда идея.
Защо?
Ако сте нов потребител в GitHub - решението за Вас е възможно най-просто: помислете добре, преди да създавате Repository-та! Аз си правих ново за всеки курс - беше удобно, леко и бързо се сваляше кода, изглеждаше подредено, НО - курсовете сега стават прекалено много. И намирам за грозно да имам repo за всеки курс :D Но не исках просто да изтрия всичко и да го кача на ново - това е too lame. Искам и да се пази историята. Нещата се усложняват обаче с факта, че си правя streak в GitHub в момента и една грешна стъпка би ми го съсипала. При изтриване на репозитори - се трие цялата история, свързана с него. Това добави сериозна доза адреналин към цялото приключение, хаха. Та - целта беше ясна: по някакъв начин да се merge-нат всички repo-та с домашни в едно общо под името на SoftUni - да стане по-подредено и чистичко.
С какво?
С gitbash, разбира се :D Това е истината, хаха.
Как?
Това е само един от многобройните начини, по които може да се постигне целта, но ми се стори най-прост, а най-важното е, че работи:
1. Създаваме ново repository, в което ще съберем всички останали. Всяко добавено repo ще бъде в отделна папка в общото - може да го кръстим Software-University-Courses (например). Клонираме го и после забравяме за него. Ще ви кажа кога да се сетите xD
$ git clone https://github.com/Y-Lyn-10/Software-University-Courses.git
2. Трябва да "подготвим" файловете за местене - създаваме копие на репото, което искаме да преместим в общото. Например, искаме да преместим CSharp-Basics. За целта го клонираме в директорията, в която ще "експериментираме" - извън Software-University-Courses репото! Линковете в командите, които пиша в този пост са примерни. Добра идея е и да се изтрие връзката с оригиналното репо, за да се предпазим от евентуални случайни промени (git remote rm origin)
$ git clone https://github.com/Y-Lyn-10/CSharp-Basics.git
$ cd CSharp-Basics
$ git remote rm origin
3. Тук идва най-важната част: следната команда минава през цялата история и файлове като трие всичко, което е извън директорията. На мен винаги ми изписва "Found nothing to rewrite", но на доста места се споменава колко е важно, та сигурно прави нещо... важно? : D
$ git filter-branch --subdirectory-filter CSharp-Basics -- --all
Препоръчвам навсякъде да пишете едно и също име, а именно - това на repo-то. Дори и да не е това, което искате да бъде като име на папка в новото репо - накрая ще си го преименувате лесно. В противен случай може да не проработи нещо.
4. Следващите две команди са за създаване на нова директория, която ще искате да преместите впоследствие. Това е направено с цел - в случай, че искате а преместите само някои файлове, а не всички. Е, ние ще местим всичко (звездичката отговаря за това)
$ mkdir CSharp-Basics
$ mv * CSharp-Basics
! Тук ще получите подобно съобщение от git: "mv: cannot move `CSharp-Basics' to `CSharp-Basics/CSharp-Basics'" - не му се плашете - нормално е да не може да премести себе си в себе си - но командата си е свършила работата за всички останали файлове и ако погледнете - те вече ще са във вътрешната папка със същото име.
5. Накрая пишете вече добре познатите ви команди - добавяне и описване на промените.
Внимание! Ако случайно сте имали разни мета-файлове и конфигурации от сорта на .idea, .gitignore, .README.md или други - изтрийте ги преди това, защото може да станат страшни конфликти. Не, че има нещо лошо в тях за упражнение де :D
$ git add --all
$ git commit -m "Ready to merge with Software-University-Courses Repo"
Останаха ни само още няколко команди, но работа в тази папка повече нямаме и отиваме в директорията на новото репо. $ cd ../Software-University-Courses/
6. Създаваме връзка със CSharp-Basics репозиторито като клон (branch) на общото репозитори. "Скелета" е следният: git remote add <прозволно име на branch-а> <директорията на папката, която искаме да преместим> Не забравяме, че папката със CSharp репото е в горната директория. Тогава пишем така:
$ git remote add CSharp ../CSharp-Basics/
7. С git pull копираме едновременно файловете и историята. Може и да се merge-нат branch-овете. Но тази семпла команда си работи добре. С командата по-долу казваме "дръпни ми цялото съдържание от CSharp клона в главния (master)"
$ git pull CSharp master
8. Накрая трием CSharp branch-a, защото не ни трябва. Push-ваме стореното и задържаме дъх дали сме направили нещата вярно...
$ git remote rm CSharp
$ git push
9. И Voila! Всъщност, старото репо все още ще се намира в профила ви - и може първо да проверите историята на къмитите в общото репо, да се убедите(или не), дали всичко е наред и чак след това ръчно да изтриете старото репозитори (в него -> settings -> delete repository)
За да преместите други репо-та, просто повторете за тях стъпките от 2 до 9 : )
Резултат - всяка цветна линия е била репозитори "в предишният си живот".
Също така, както споменах - този метод може да се ползва и само за единично преместване на файлове - следователно така ще можете и да разделите някое твърде обемно репозитори на няколко по-малки или просто да преместите нещо. Тогава вместо да избирате със звездичка всичко, посочвате отделни папки или файлове. И, разбира се - внимавайте в коя директория се намирате.
Успех! Ако имате въпроси, нещо ви е неясно или има проблем - пишете свободно в тази тема. Благодаря за вниманието : )
PS. Искам да се извиня, задето сега всичките домашни, които споделях във форума са със счупени линкове :/ Решенията са си все още качени, просто са в новото репо. Пък аз ще се постарая когато мога - да едитвам някои от отговорите си в съответните теми :)