-
1. Почеток
- 1.1 За верзиска контрола
- 1.2 Кратка историја на Git
- 1.3 Основи на Гит
- 1.4 Командната линија
- 1.5 Инсталирање на Git
- 1.6 First-Time Git Setup
- 1.7 Getting Help
- 1.8 Заклучок
-
2. Основите на Git
-
3. Гранење во Git
- 3.1 Гранење објаснето
- 3.2 Основно разгранување и спојување
- 3.3 Branch Management
- 3.4 Работни процеси
- 3.5 Далечински гранки
- 3.6 Ребаза
- 3.7 Заклучок
-
4. Git на Сервер
- 4.1 Протоколите
- 4.2 Добивање на Git на сервер
- 4.3 Генерирање на вашиот SSH јавен клуч
- 4.4 Поставување на серверот
- 4.5 Гит демон
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Опции за домаќини на трети лица
- 4.10 Заклучок
-
5. Дистрибуиран Git
- 5.1 Дистрибуирани работни процеси
- 5.2 Придонес кон проект
- 5.3 Приватен мал тим
- 5.4 Одржување на проект
- 5.5 Заклучок
-
6. GitHub
-
7. Git Алатки
- 7.1 Revision Selection
- 7.2 Интерактивно стажирање
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Напредно спојување
- 7.9 Rerere
- 7.10 Дебагирање со Git
- 7.11 Submodules
- 7.12 Збивање
- 7.13 Заменување
- 7.14 Складирање на ингеренции
- 7.15 Заклучок
-
8. Персонализација на Git
- 8.1 Git Configuration
- 8.2 Git Атрибути
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Заклучок
-
9. Git и други системи
- 9.1 Git како Клиент
- 9.2 Мигрирање кон Git
- 9.3 Заклучок
-
10. Внатрешноста на Git
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Заклучок
-
A1. Appendix A: Git во други околини
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Заклучок
-
A2. Appendix B: Вметнување на Git во вашите апликации
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
-
A3. Appendix C: Git команди
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
7.13 Git Алатки - Заменување
Заменување
Како што веќе нагласивме, објектите во објектната база на податоци на Git се непроменливи, но Git обезбедува интересен начин да pretend да ги замени објектите во својата база на податоци со други објекти.
Командата replace
ви овозможува да наведете објект во Git и да кажете" секој пат кога ќе се повикате на this објект, да се преправате дека е different објект ".
Ова е најчесто корисно за замена на една обврска во историјата со друга, без да мора да ја обнови целата историја со, на пример, git filter-branch
.
На пример, да речеме дека имате голема историја на код и сакате да го поделите вашето складиште во една кратка историја за нови програмери и една многу подолга и поголема историја за луѓето заинтересирани за рударство. Можете да префрлите една историја врз друга со "замена" на најстариот залог во новата линија со најновиот залог за постариот. Ова е убаво, бидејќи тоа значи дека всушност не морате да ја преработите секоја заложба во новата историја, како што обично треба да направите за да ги споите заедно (бидејќи родителството влијае на SHA-1s).
Ајде да го пробаме ова.
Да земеме постоечко складиште, да го поделиме во две складишта, еден неодамнешен и еден историски, а потоа ќе видиме како можеме да ги рекомбинираме без да ги смениме неодамнешните складишта SHA-1 вредности преку replace
.
Ќе користиме едноставно складиште со пет едноставни обврски:
$ git log --oneline
ef989d8 fifth commit
c6e1e95 fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Ние сакаме да го разделиме ова во две линии на историјата. Една линија оди од изврши еден да изврши четири - тоа ќе биде историски. Втората линија само ќе се изврши четири и пет - тоа ќе биде неодамнешната историја.
Па, креирањето на историската историја е лесно, можеме само да ставиме филијала во историјата, а потоа да ја притиснеме таа гранка до главната гранка на ново оддалечено складиште.
$ git branch history c6e1e95
$ git log --oneline --decorate
ef989d8 (HEAD, master) fifth commit
c6e1e95 (history) fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Сега можеме да извршиме притисок врз новата гранка "историја" во "господарната" гранка на нашето ново складиште:
$ git remote add project-history https://github.com/schacon/project-history
$ git push project-history history:master
Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (12/12), 907 bytes, done.
Total 12 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (12/12), done.
To git@github.com:schacon/project-history.git
* [new branch] history -> master
Добро, па нашата историја е објавена. Сега потешките делови ја намалуваат нашата понова историја, па затоа е помала. Потребно е преклопување за да можеме да го замениме извршувањето во една со еквивалентно извршување во другата, па затоа ќе го скратиме ова за да правиме само четири и пет (па извршиме четири преклопувања).
$ git log --oneline --decorate
ef989d8 (HEAD, master) fifth commit
c6e1e95 (history) fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Корисно е во овој случај да се создаде основен обврзник кој има инструкции за проширување на историјата, па затоа други развивачи знаат што да прават ако го погодат првото извршување во скратената историја и им треба повеќе. Значи, она што ќе го направиме е да создадеме првичен објект за извршување како наша основна точка со инструкции, а потоа да ги ребритираме останатите обврски (четири и пет) на врвот од неа.
За да го сториме тоа, треба да избереме точка за да се поделиме, што за нас е третата обврска, која е 9c68fdc
во SHA-говорот.
Значи, нашата основа ќе се заснова на тоа дрво.
Ние можеме да ја создадеме основната обврска користејќи ја командата commit-tree
, која зазема само едно дрво и ќе ни даде сосема нов објект за SHA-1 без родители.
$ echo 'get history from blah blah blah' | git commit-tree 9c68fdc^{tree}
622e88e9cbfbacfb75b5279245b9fb38dfea10cf
Note
|
Командата |
Добро, па сега кога имаме основен залог, можеме да ја оспориме остатокот од нашата историја на врвот на тоа со git rebase -onto
.
Аргументот --onto
ќе биде SHA-1 што се вративме од` commit-tree`, а точка на rebase ќе биде третата обврска (родителот на првата обврска која сакаме да ја зачуваме, 9c68fdc
):
$ git rebase --onto 622e88 9c68fdc
First, rewinding head to replay your work on top of it...
Applying: fourth commit
Applying: fifth commit
Добро, па сега повторно ја напишавме нашата понова историја на врвот на фрлање база обврски што сега има инструкции во него за тоа како да се реконструира целата историја ако сакаме да. Ние можеме да ја поттикнеме таа нова историја во нов проект, а сега кога луѓето ќе клонираат тоа складиште, ќе ги видат само најновите две обврски, а потоа базата ќе извршат со инструкции.
Ајде сега да ги префрлиме улогите на некој кој го клонира проектот за прв пат кој сака целата историја. За да ги добиете податоците од историјата по клонирањето на ова скратено складиште, ќе треба да додадете втор далечински управувач за историското складиште и да донесам:
$ git clone https://github.com/schacon/project
$ cd project
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
622e88e get history from blah blah blah
$ git remote add project-history https://github.com/schacon/project-history
$ git fetch project-history
From https://github.com/schacon/project-history
* [new branch] master -> project-history/master
Сега соработникот ќе ги има своите неодамнешни обврски во гранката "господар" и историчарот се обврзува во гранката "проект-историја / господар".
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
622e88e get history from blah blah blah
$ git log --oneline project-history/master
c6e1e95 fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
За да ги комбинирате, едноставно можете да го повикате git replace
со обврската што сакате да ја замените, а потоа и за извршувањето со кое сакате да го замените.
Затоа сакаме да го замениме "четвртото" извршување во главната гранка со "четврто" извршување во гранката "проект-историја / господар":
$ git replace 81a708d c6e1e95
Сега, ако погледнете во историјата на master
филијалата, се чини дека изгледа вака:
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Кул, нели? Без да мораме да ги промениме сите SHA-1 наспроти низводно, можевме да замениме една обврска во нашата историја со сосема поинаква заложба и сите нормални алатки (bisect
,` blame`, итн.) Ќе работат како би очекувале тие да .
Интересно е што сè уште покажува 81a708d
како SHA-1, иако всушност ги користи податоците за commit` c6e1e95` со кои сме го замениле.
Дури и ако извршите команда како cat-file
, таа ќе ви ги прикаже заменетите податоци:
$ git cat-file -p 81a708d
tree 7bc544cf438903b65ca9104a1e30345eee6c083d
parent 9c68fdceee073230f19ebb8b5e7fc71b479c0252
author Scott Chacon <schacon@gmail.com> 1268712581 -0700
committer Scott Chacon <schacon@gmail.com> 1268712581 -0700
fourth commit
Запомнете дека вистинскиот родител на 81a708d
беше нашиот залог на место (` 622e88e`), а не 9c68fdce
, како што е наведено тука.
Друга интересна работа е што овие податоци се чуваат во нашите референци:
$ git for-each-ref
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/heads/master
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/remotes/history/master
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/HEAD
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/master
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/replace/81a708dd0e167a3f691541c7a6463343bc457040
Ова значи дека е лесно да ја споделиме нашата замена со други, бидејќи можеме да го притиснеме ова на нашиот сервер, а другите луѓе лесно може да го преземат. Ова не е толку корисно во сценариото за пресадување на историјата што ние го поминавме овде (бидејќи секој ќе ги презема двете истории во секој случај, па зошто да ги одвои?), Но може да биде корисно и во други околности.