常用回退操作
首先给出一些常用回退操作参考:
git checkout .
回退没有add到暂存区的更改
git reset --hard
回退所有add到和没有add到暂存区的更改。后面如果跟上commit或者分支名,也可以直接变更已经commit的更改,原理是将分支名或HEAD指针重新指向。
git clean -df
删除没有add的其他文件和目录。如果已经add而没有commit,用git reset --hard
的时候就会删除。
git notes
手撸git实录
git object
three attributes:
- type
- size
- content
and has a hash name, computed with these 3 attributes
git directive analysis
git init
create this directory structure in one empty directory. 这是满足git初始化条件最低的目录结构
.
└─.git
│ config
│ description
│ HEAD
│
├─hooks
├─info
│ exclude
│
├─objects
│ ├─info
│ └─pack
└─refs
├─heads
└─tags
git add test.txt
create binary compress file for a.txt(git object).
can be done by
git hash-object -w test.txt
. even the file is empty, the meta info of the file will be compressed and stored in git object.a hash string is printed on the screen, just like
3b18e512dba79e4c8300dd08aeb37f8e728b8dad
. you can usegit cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad
command to see the files’ contentadd a.txt into index.
can be done by
git update-index --add --cacheinfo 100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad test.txt
. if the file is already in index and just updated to a new version, it is ok to run justgit update-index test.txt
.than
.git/index
will be updated. usegit ls-files --stage
to look its content.
git commit
create tree object
git write-tree
store a tree object and show the hash SHA-1. actually save index’s content.
create commit object accroding tree object and parent commit object(*)
echo 'commit message' | git commit-tree <tree-hash> -p <last-commit-hash -p <last-commit-hash>
if there are twoparent commit
means this is a merge commita commit object will be stored and show the hash SHA-1.
commit contains info just like:
tree bcf9e352e75e1997deafc956292b33ee7c207553
parent 498eca8a43098c77c6b7c164cdf9d5b8aeb76f54
author claws <jingjiecb@gmail.com> 1637236383 +0800
committer claws <jingjiecb@gmail.com> 1637236383 +0800
add a.txt from master
if it is the initial commit, there will be no parent. else if it is a merge commit, there will be two parents
git log
- read .git/HEAD and get the branch pointer’s name(branchName)
- read .git/refs/heads/branchName to get the commit(snapshoot) hash
- git cat-file -p hash and get the massage of this commit, and the parent(‘s) commit hash(if has)
- repete 3 until initial commit
git checkout
checkout files: set the file with the content in git object. usually use git checkout -- filePath
to abondon the modifying in work tree.
checkout tag head commit: set the HEAD pointer to it, then set index the tree in the commit object, then set all files same with the object in the tree.
you can use git checkout --ours test.txt
to select our version while merging, or use git checkout --theirs test.txt
to select their version.
use git --work-tree=path/to/other/directory checkout -- .
to checkout all files in git repository to other directory instead of current work directory.
warning: may generate detached head problem. modify the .git/HEAD file directly can solve the problem
git reset
reset the current branch’s pointer to some commit. has 3 mode: –mixed(default), –hard, –soft
- –mixed(Default) will not change current work tree files. but will change index same with the tree in that commit.
- –soft will only change the current branch pointer to one commit. without change the workspace and index(stage)
- –hard will change the branch pointer, index and the workspace. workspace will be changed thoroughly(all file in index will be reset, new file will be deleted. but files not in index will not be influenced)
git merge
there are 3 situations when merge:
- fast forward. no further commit on this branch, so just move the branch pointer to the coming branch’s latest commit.
- auto-solve merge. no conflict happened, git apply both modifying, and generate a new commit whose parents are the current commit and the coming commit.
- conflict merge. conflict happened, and must be desided manually. After all conflict solved, add and commit the change
the last two situations both generate a new merge commit.
git pull
by default, git fetch
then git merge romote/master
(e.g.)
git rebase
undo all modifying, checkout to the other commit(or branch or tag), the reapply the modifying there.
might cause rebase conflict.
use git pull --rebase
to change pull stategy to rebase pull, first git fetch
then git rebase remot/master
(e.g.)