Qualified
- Fundamental concepts: revisions, working copy, repository
- Getting (checking out) data from repository
- Examining local changes, comparing working copy to repository
- Updating working copy, merging changes
- Updating to specific version
- Examining change history
- Discarding changes
- Resolving conflicts in code
- Copying, moving files, folders in repository
- Committing changes
- Creating, discovering and breaking locks (if supported)
Fundamental concepts: revisions, working copy, repository
Solutions for versioning models
- Lock-Modify-Unlock
- Copy-Modify-Merge
Repository - is a central store of data. It stores information in the form of a filesystem tree. It like file server with changes history
Working copy - a local reflection of the repositories files and directories. Users then work simultaneously and independently, modifying their private copies. Finally, the private copies are merged together into a new, final version
Revision is a tracked state of project. Every revision in git have it's own
sha-1hash, and can be referenced by it
<sha1>, e.g. 'dae86e1950b1277e545cee180551750029cfe735', 'dae86e'<refname>, e.g. 'master', 'heads/master', 'refs/heads/master'
HEAD is synthetic branch, that always points to the currently checked out revision.
Getting (checking out) data from repository
- init
git init
git add Readme.md
git commit -m 'initial project version'
- clone
git clone git://github.com/repo/my.git
Examining local changes, comparing working copy to repository
git status
untracked => git add Readme.md
git add Readme.md for indexing
git diff (сравнивает НЕиндексированные изменения с последним коммитом)
git diff --staged (сравнивает индексированные изменения с последним коммитом)
- git rm - удалить
для отображения изменений
Updating working copy, merging changes
git commit -m 'add README.md'git mv Readme.md read.md
Examining change history
git log-pразница, внесенная коммитом-2показать только n последних записи--statстатистика ( 1 files changed, 1 insertions(+), 1 deletions(-))--pretty- форматировать вывод--graph- выводит граф
Отмена изменений
git reset --hard HEADсбрасывает все локальные измененияgit checkout -- <file>- сбрасывает внесенные изменения для конкретного файлаgit revert <commit>создает новый коммит, который откатывает измененияgit commit --amendобновляет последний коммит (незапушенный)git reset HEAD benchmarks.rb- сбрасывает индексацию файла (изменения остаются)git blame <file>- показывает кто и когда изменял этот файл
Применение изменений
git pullgit pushgit fetch
Discarding changes
Changing Your Last Commit
git commit --amend
This command takes your staging area and uses it for the commit. If you’ve have made no changes since your last commit (for instance, you run this command it immediately after your previous commit), then your snapshot will look exactly the same and all you’ll change is your commit message.
$ git commit -m ’initial commit’
$ git add forgotten_file
$ git commit --amend
All three of these commands end up with a single commit — the second command replaces the results of the first.
Unstaging a Staged File
For example, let’s say you’ve changed two files and want to commit them as two separate changes, but you accidentally type git add * and stage them both. How can you unstage one of the two? to unstage one of files:
git reset HEAD <file>..."
for exmple:
$ git reset HEAD benchmarks.rb
benchmarks.rb: locally modified
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: benchmarks.rb
#
The command is a bit strange, but it works. The benchmarks.rb file is modified but once again unstaged.
Unmodifying a Modified File
What if you realize that you don’t want to keep your changes to the benchmarks.rb file? How can you easily unmodify it — revert it back to what it looked like when you
last committed (or initially cloned, or however you got it into your working directory)? git checkout -- <file>... to discard changes in working directory
$ git checkout -- benchmarks.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README.txt
#
You can see that the changes have been reverted. You should also realize that this is a dangerous command: any changes you made to that file are gone — you just copied another file over it. Don’t ever use this command unless you absolutely know that you don’t want the file.
Resolving conflicts in code
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Git hasn’t automatically created a new merge commit. It has paused the process while you resolve the conflict. If you want to see which files are unmerged at any point after a merge conflict, you can run git status:
[master*]$ git status
index.html: needs merge
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# unmerged: index.html
#
Anything that has merge conflicts and hasn’t been resolved is listed as unmerged. Git adds standard conflict-resolution markers to the files that have conflicts, so you can open them manually and resolve those conflicts. Your file contains a section that looks something like this:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
53
PRO GIT SCOTT CHACON
</div>
>>>>>>> iss53:index.html
This means the version in HEAD (your master branch, because that was what you had checked out when you ran your merge command) is the top part of that block (everything above the =======), while the version in your iss53 branch looks like everything in the bottom part. In order to resolve the conflict, you have to either choose one side or the other or merge the contents yourself.
$ git mergetool
merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff
After all, You can modify that message with details about how you resolved the merge if you think it would be helpful to others looking at this merge in the future — why you did what you did, if it’s not obvious.
Copying, moving files, folders in repository
Git doesn’t explicitly track file movement. If you rename a file in Git, no metadata is stored in Git that tells it you renamed the file. However, Git is pretty smart about figuring that out after the fact — we’ll deal with detecting file movement a bit later. Thus it’s a bit confusing that Git has a mv command. If you want to rename a file in Git, you can run something like
$ git mv file_from file_to
However, this is equivalent to running something like this:
$ mv README.txt README
$ git rm README.txt
$ git add README
Git figures out that it’s a rename implicitly, so it doesn’t matter if you rename a file that way or with the mv command. The only real difference is that mv is one command instead of three — it’s a convenience function. More important, you can use any tool you like to rename a file, and address the add/rm later, before you commit
Committing changes
$ git commit
$ git commit -m "Story 182: Fix benchmarks for speed"
Creating, discovering and breaking locks (if supported)
Git работает по модели Copy-Modify-Merge, потому не использует locks