Git
Chapters ▾ 2nd Edition

2.2 Основите на Git - Снимање на промени во складиштето

Снимање на промени во складиштето

Во овој момент, треба да имате бона фиде Git складиште на вашата локална машина, како и проверка или working copy од сите негови датотеки пред вас. Обично, ќе сакате да започнете да правите промени и да направите снимки од тие промени во вашето складиште секој пат кога проектот ќе достигне држава која сакате да ја снимите.

Запомнете дека секоја датотека во вашиот работен директориум може да биде во една од двете состојби: tracked или untracked. Следните датотеки се датотеки што беа во последната слика; тие можат да бидат немодифицирани, модифицирани или изведени. На кратко, следени датотеки се датотеки за кои знае Git.

Непривлечените датотеки се сè друго - сите датотеки во вашиот работен директориум, кои не беа во вашата последна слика и не се наоѓаат во вашата област на поставеност. Кога првпат клонирате складиште, сите ваши датотеки ќе бидат следени и немодифицирани, бидејќи Git ги проверуваше и немате ништо изменето.

Додека ги уредувате датотеките, Git ги гледа како модифицирани, затоа што сте ги промениле од последното извршување. Додека работите, селективно ги фаќате овие изменети датотеки, а потоа ги извршувате сите оние изведени промени, а циклусот се повторува.

The lifecycle of the status of your files.
Figure 8. The lifecycle of the status of your files.

Проверка на статусот на вашите датотеки

Главната алатка што ја користите за да утврдите кои датотеки се во која држава е командата git status. Ако ја извршите оваа команда директно по клон, треба да видите нешто како ова:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Ова значи дека имате чист работен директориум - со други зборови, ниту една од вашите следени датотеки не е модифицирана. Git, исто така, не гледа никакви необучени датотеки, или тие би биле наведени тука. Конечно, командата ти кажува во која гранка си, и ве информира дека не се одвоила од истата гранка на серверот. За сега, таа гранка е секогаш ‘` господар '’, што е стандардно; нема да се грижиш за тоа овде. Гранење во Git детално ќе ги пренесе гранките и референциите.

Да речеме да додадете нова датотека во вашиот проект, едноставна датотека "README". Доколку датотеката не постоела порано, и ја извршувате git status, ја гледате вашата необјавена датотека како:

$ echo 'My Project' > README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    README

nothing added to commit but untracked files present (use "git add" to track)

Можете да видите дека вашата нова README-датотека е отфрлена, бидејќи е под насловот ,, Неинтресирани датотеки '' во вашиот статус излез. Несетената содржина во основа значи дека Git гледа датотека што немате во претходната слика (commit); Git нема да започне вклучително и во вашите снимки за обврски додека не го известите експлицитно да го сторите тоа. Тоа го прави ова за да не случајно почнувате вклучувајќи генерирани бинарни датотеки или други датотеки што не сте сакале да ги вклучите. Вие сакате да започнете со "README", па да почнеме да ја следиме датотеката.

Следење на нови датотеки

За да започнете со следење на нова датотека, ја користите командата git add. За да започнете со следење на датотеката README, можете да го направите ова:

$ git add README

Ако повторно ја извршите вашата команда за статус, можете да видите дека вашата датотека README сега е следена и изведена да биде извршена:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Можете да кажете дека е изведена поради тоа што е под заглавието Промените да биде извршено '. Ако извршиш во овој момент, верзијата на датотеката во моментот кога ќе трчаше "git add" е она што ќе биде во историската снимка. Може да се сетиш дека кога претходно сте тргнале на `git init, тогаш трчате` git add <files> - тоа беше да започнете со следење на датотеки во вашиот директориум.(((git commands, init)))(((git commands, add))) Командата `git add зема име за патека за датотека или директориум; ако тоа е директориум, командата додава сите датотеки во тој директориум рекурзивно.

Поставување на модифицирани датотеки

Ајде да ја смениме датотеката која веќе беше следена. Ако промените претходно следена датотека наречена CONTRIBUTING.md, а потоа повторно ја извршите командата` git status`, добивате нешто што изгледа вака:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Датотеката CONTRIBUTING.md се појавува под делот наречен` Промени неизведени за commit '' - што значи дека датотеката што е следена е модифицирана во работниот директориум, но сеуште не е изведена. За да го поставите, ја извршувате командата `git add. git add е повеќенаменска команда - ја користите за да започнете со следење на нови датотеки, за да фаќате датотеки, и да правите други работи како означување на спојуваните датотеки како решени. Може да биде корисно да се размислува за тоа повеќе како "да ја додадете токму оваа содржина на следното извршување", наместо "да ја додадете оваа датотека во проектот". Ајде да го стартуваме git add сега за да ја прикачи датотеката` CONTRIBUTING.md`, а потоа повторно да го стартува git status:

$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Двете датотеки се изведени и ќе одат во вашиот следен залог. Во овој момент, претпоставувам дека се сеќавате на една мала промена што сакате да ја направите во CONTRIBUTING.md пред да ја извршите. Го отварате повторно и направете ја таа промена и подготвени сте да извршите. Сепак, ајде да го извршуваме "git status" уште еднаш:

$ vim CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Што по ѓаволите? Сега CONTRIBUTING.md е наведена како изведена како and unstaged. Како е тоа можно? Излегува дека Git ја фати датотеката токму онака како што е кога ја извршувате командата git add. Ако се изврши сега, верзијата на CONTRIBUTING.md, како што беше, кога последен пат ја извршуваше командата` git add`, е како ќе оди во извршувањето, а не во верзијата на датотеката како што изгледа во вашиот работен директориум, кога извршете git commit. Ако ја модифицирате датотеката откако ќе ја стартувате git add ', мора повторно да ја стартувате git add` за да ја поставите најновата верзија на датотеката:

$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Краток статус

Додека излезот git status е прилично сеопфатен, исто така е сосема зборлив. Git, исто така, има кратко статус знаме, па можете да ги видите вашите промени на повеќе компактен начин. Ако извршите git status -s или` git status -short`, добивате многу поедноставен излез од командата:

$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

Новите датотеки што не се следени имаат "??" до нив, новите датотеки што се додадени во сценариото имаат A, изменетите датотеки имаат` M` и така натаму. Во излезот има две колони - левата колона го означува статусот на местото каде што е поставена, а десната колона го покажува статусот на работното стебло. Така, на пример, во тој излез, датотеката README е модифицирана во работниот директориум, но сеуште не е изведена, додека датотеката` lib / simplegit.rb` е модифицирана и изведена. Rakefile беше модифициран, изведена, а потоа модификувана повторно, така што има промени во него, кои се изведени и неизведени.

Игнорирање на датотеки

Често, ќе имате класа на датотеки за кои не сакате Git автоматски да ги додава или дури да ви покаже дека се неинтегрирани. Овие се генерално автоматски генерирани датотеки како што се лог датотеки или датотеки произведени од вашиот систем за изградба. Во такви случаи, можете да креирате шаблони за наведување на датотеки за да ги совпаѓаат со име ".gitignore". Еве пример пример: .gitignore:

$ cat .gitignore
*.[oa]
*~

Првата линија му кажува на Git да ги игнорира сите датотеки што завршуваат со ‘` .o ’ или `` .a ' - датотеки со објект и архиви кои можат да бидат производ за градење на вашиот код. Втората линија му кажува на Git да ги игнорира сите датотеки чии имиња завршуваат со тилда (~), што го користат многу уредувачи на текст како што се Emacs за означување на привремени датотеки. Вие исто така може да вклучите дневник, tmp или pid директориум; автоматски генерирана документација; и така натаму. Поставувањето датотека .gitignore за вашето ново складиште пред да започнете е генерално добра идеја, па не случајно да ги извршувате датотеките што навистина не ги сакате во Вашето складиште за Git.

Правилата за шаблоните што можете да ги ставите во датотеката .gitignore се следниве:

  • Празни линии или линии почнувајќи со "#" се игнорираат.

  • Стандардни шаблони за работа функционираат, и ќе се применуваат рекурзивно низ целиот работен стебло.

  • Можете да започнете обрасци со коса црта (/) за да избегнете рекурзивност.

  • Можете да ги завршите обрасците со коса црта (/) за да наведете директориум.

  • Можете да го негирате моделот со стартување со фантастичен (`! ').

Шаблоните за глобус се како поедноставени регуларни изрази што ги користат школките. Ѕвездичка (*) се совпаѓа со нула или повеќе знаци; [abc] одговара на секој карактер во загради (во овој случај a, b, или c); прашалник (?) одговара на еден карактер; и загради што ги прикажуваат знаците разделени со цртичка ([0-9]) се совпаѓаат со било кој карактер помеѓу нив (во овој случај од 0 до 9). Можете исто така да користите две ѕвездички за да ги совпаѓате вгнездените директориуми; a / ** / z ќе одговара на` a / z`, a / b / z,` a / b / c / z` и така натаму.

Еве уште еден пример .gitignore датотека:

# ignore all .a files
*.a

# but do track lib.a, even though you're ignoring .a files above
!lib.a

# only ignore the TODO file in the current directory, not subdir/TODO
/TODO

# ignore all files in the build/ directory
build/

# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt

# ignore all .pdf files in the doc/ directory and any of its subdirectories
doc/**/*.pdf

GitHub одржува прилично сеопфатна листа на добри примери за ".gitignore" датотеки за десетици проекти и јазици на https://github.com/github/gitignore ако сакате појдовна точка за вашиот проект.

Во едноставен случај, складиштето може да има една датотека .gitignore во root директориумот, што рекурзивно се однесува на целото складиште. Сепак, исто така е можно да имате дополнителни .gitignore датотеки во поддиректориуми. Правилата во овие вгнездени датотеки .gitignore се однесуваат само на датотеките под директориумот каде што се наоѓаат. (Репозиториумот за извор на кернелот на Linux има 206 .gitignore датотеки.)

Не е во опсегот на оваа книга да се влезе во деталите на повеќекратните .gitignore датотеки; видете man gitignore за деталите.

Преглед на вашите изведени и неискористени промени

Ако командата git status е премногу нејасна за вас - сакате да знаете точно што сте го смениле, а не само што датотеките беа променети - можете да ја користите командата` git diff`. (Git commands, diff ) Подоцна ќе ги покриеме "git diff", но најверојатно ќе го користите најчесто за да одговорите на овие две прашања: Што сте се промениле, но сé уште не изведени? И што направивте дека ќе се посветите? Иако git status одговара на овие прашања многу генерално со наведување на имињата на датотеките,` git diff` ви ги покажува точните линии кои се додадени и отстранети - лепенката, како што беше.

Да речеме дека повторно ќе ја уредите и ќе ја фатиме датотеката README повторно, а потоа уредувајте ја датотеката` CONTRIBUTING.md` без да ја поставите. Ако ја извршите командата git status, повторно ќе видите нешто слично:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

За да видите што сте се промениле, но сѐ уште не изведена, напишете git diff без други аргументи:

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's

Оваа команда го споредува она што е во вашиот работен директориум со она што е во вашата област на поставување. Резултатот ви ги кажува промените што сте ги направиле дека сеуште не сте изведени.

Ако сакате да видите што сте изведени, што ќе одат во вашата следна залог, можете да го користите git diff -staged. Оваа команда ги споредува вашите изведени промени со вашата последна обврска:

$ git diff --staged
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+My Project

Важно е да се забележи дека "git diff" сама по себе не ги покажува сите промени направени по последната посветеност - само промените кои сеуште не се прикажани. Ако сте изложиле сите ваши промени, git diff нема да ви даде излез.

За друг пример, ако ја фати датотеката CONTRIBUTING.md и потоа ја уредите, можете да го користите` git diff` за да ги видите промените во датотеката што се изведуваат и промените што не се поставени. Ако нашата околина изгледа вака:

$ git add CONTRIBUTING.md
$ echo '# test line' >> CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Сега можете да го користите git diff за да видите што е уште неискористено:

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 643e24f..87f08c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -119,3 +119,4 @@ at the
 ## Starter Projects

 See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md).
+# test line

и git diff -cached за да видите што досега сте го изведеле (` -staged` и --cached се синоними):

$ git diff --cached
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's
Example 1. Git Diff in an External Tool

Ние ќе продолжиме да ја користиме командата git diff на различни начини во текот на остатокот од книгата. Постои уште еден начин да се разгледаат овие разлики ако претпочитате графичка или надворешна програма за разгледување на разлики. Ако го стартувате git difftool наместо` git diff`, можете да ги видите сите овие разлики во софтверот како што се emerge, vimdiff и многу други (вклучувајќи комерцијални производи). Извршете git difftool --tool-help за да видите што е достапно на вашиот систем.

Извршување на промените

Сега, кога вашата област за поставување е поставена онака како што сакате, можете да ги извршите вашите промени. Запомнете дека сè што е сè уште неиспоставен - сите датотеки што сте ги создале или промените дека не сте го вклучиле "git add", бидејќи сте ги уредувале - нема да одат во оваа залог. Тие ќе останат како изменети датотеки на вашиот диск. Во овој случај, да речеме дека последен пат кога трчате "git status", сте виделе дека сè е изведено, така што сте подготвени да ги извршите вашите промени. Најлесен начин за извршување е да напишете git commit:

$ git commit

Со тоа го отвора вашиот уредник по избор. (Ова е поставено од променливата на променливата на EDITOR на вашиот школка - обично vim или emacs, иако можете да го конфигурирате со она што сакате со командата` git config --global core.editor` како што сте виделе во << ch01-добивање-почеток >>).

Уредувачот го прикажува следниов текст (овој пример е Vim екран):

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Your branch is up-to-date with 'origin/master'.
#
# Changes to be committed:
#	new file:   README
#	modified:   CONTRIBUTING.md
#
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C

Можете да видите дека стандардната порака за заем содржи најнов излез од командата git status, коментирана и една празна линија на врвот. Можете да ги отстраните овие коментари и да напишете порака за извршување, или можете да ги оставите таму за да ви помогнам да се сетите на она што го извршувате. (За уште појасен потсетник за она што сте го модифицирале, можете да ја пренесете опцијата -v во` git commit '. Со тоа, исто така, се става разликата во промената во уредувачот за да може точно да се види какви промени извршувате.) Кога ќе излезете од уредувачот, Git ќе ја креира вашата заложба со таа порака за предавање (со коментари и раздвојувања).

Алтернативно, можете да ја напишете вашата порака за обврски во линија со командата commit, така што ќе ја наведете по знамето` -m`:

$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
 2 files changed, 2 insertions(+)
 create mode 100644 README

Сега сте го создале вашето прво извршување! Можете да видите дека извршувањето ви даде извесен резултат за себе: која гранка сте посветиле на (господар), што проверува SHA-1 на извршителите (` 463dc4f`), колку датотеки се променети, и статистика за линиите и отстранети во извршувањето.

Запомнете дека обврската за снимање на снимката што сте ја поставиле во вашата област на поставеност. Сè што не сте го сториле се уште седи таму модифицирано; можете да направите друга обврска за да ја додадете во историјата. Секој пат кога ќе извршите залог, снимате слика од вашиот проект со кој можете да се вратите или да ги споредите подоцна.

Прескокнување на просторот за поставување

И покрај тоа што може да биде неверојатно корисно за изработката, тој точно се определува како што сакате, а понекогаш и местото за поставување понекогаш е покомплексно отколку што ви треба во вашиот работен проток. Ако сакате да ја прескокнете областа на поставување, Git обезбедува едноставна кратенка. Додавањето на опцијата -a во командата` git commit` го прави Git автоматски да ја фати секоја датотека што е веќе следена пред извршување на commit, овозможувајќи ви да го прескокнете делот git add:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
 1 file changed, 5 insertions(+), 0 deletions(-)

Забележете како не мора да ја стартувате git add во датотеката` CONTRIBUTING.md` во овој случај, пред да извршите. Тоа е затоа што знакот -a ги вклучува сите променети датотеки. Ова е погодно, но бидете внимателни; понекогаш ова знаме ќе предизвика да вклучите несакани промени.

Removing Files

За да отстраните датотека од Git, морате да ја отстраните од вашите следени датотеки (поточно, отстранете ја од вашата област за поставување), а потоа извршете го. Командата git rm го прави тоа, а исто така ја отстранува датотеката од вашиот работен директориум, така што не го гледате како непривлечена датотека следниот пат.

Ако едноставно ја отстраните датотеката од вашиот работен директориум, се појавува во подрачјето ‘` Измени неизведени за извршување '’ (што е, unstaged) на излезот од вашиот git status:

$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    PROJECTS.md

no changes added to commit (use "git add" and/or "git commit -a")

Потоа, ако го стартувате git rm, го фати отстранувањето на датотеката:

$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    PROJECTS.md

Следниот пат кога ќе извршите, датотеката ќе исчезне и нема повеќе да следи. Ако сте ја смениле датотеката и сте ја додале во просторот за стартување, мора да го присилите отстранувањето со опцијата -f. Ова е безбедносна карактеристика за да се спречи случајно отстранување на податоци што сеуште не се снимени во слика и кои не можат да се обноват од Git.

Друга корисна работа што можеби ќе сакате да направите е да ја задржите датотеката во вашето работно стебло, но да ја отстраните од вашата област на поставување. Со други зборови, можеби ќе сакате да ја задржите датотеката на вашиот хард диск, но да не го следите Git повеќе. Ова е особено корисно ако сте заборавиле да додадете нешто во вашата датотека .gitignore и случајно да го поставите, како голема датотека на дневник или купувани датотеки. За да го направите ова, користете ја опцијата "--cached":

$ git rm --cached README

Можете да ги пренесувате датотеките, директориумите и шаблоните на шаблони во датотеката во командата git rm. Тоа значи дека можете да направите работи како што се:

$ git rm log/\*.log

Забележете ја обратна коса црта (\) пред *. Ова е неопходно, бидејќи Git ја прави својата експанзија на датотеката во дополнение на проширувањето на името на вашата школка. Оваа команда ги отстранува сите датотеки кои имаат .log екстензија во директориумот` log / `. Или, можете да направите нешто вака:

$ git rm \*~

Оваа команда ги отстранува сите датотеки чии имиња завршуваат со ~.

Moving Files

За разлика од многу други VCS системи, Git експлицитно не го следи движењето на датотеките. Ако преименувате датотека во Git, во Git не се зачувуваат метаподатоци што велат дека сте ја преименувале датотеката. Сепак, Git е прилично паметни за да го пронајдеме тоа по фактот - ние ќе се занимаваме со откривање на движење на датотеки малку подоцна.

Така е малку збунувачки дека Git има mv команда. Ако сакате да преименувате датотека во Git, можете да извршите нешто како:

$ git mv file_from file_to

и работи добро. Всушност, ако извршите нешто слично и погледнете го статусот, ќе видите дека Git смета дека е преименувана датотека:

$ git mv README.md README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Сепак, ова е еквивалентно на тоа да се работи нешто како ова:

$ mv README.md README
$ git rm README.md
$ git add README

Git фигурира дека е преименуван имплицитно, па затоа не е важно дали преименувате датотека на тој начин или со командата mv. Единствената вистинска разлика е тоа што git mv е една команда наместо три - тоа е погодност функција. Уште поважно, можете да користите било која алатка сакате да преименувате датотека, и да се обратите на add / rm подоцна, пред да извршите.