告诉你是谁(git config)
全局设置
git config --global user.name author git config --global user.email author@corpmail.com
撤销全局设置
这些会出现在你的提交记录中,记录在~/.gitconfig 文件里
如果想取消全局设置(你存在多个git账号,一个github,一个oschina)git config --global --unset user.name git config --global --unset user.email
局部设置
对于特定项目 对应git项目目录/.git/configgit config user.name shenhuaxlt git config user.email shenhualxt@163.com
查看现有设置
git log
- 什么都没有设置: 默认系统的用户名
Author: Terry < terry@TerrydeMacBook-Pro.local>
从远程库克隆(git clone)
ssh方式
git clone git@git.oschina.net:shenhualxt111/git_practise.git Permission denied (publickey).
解决办法:
为github帐号添加SSH keys
补充:一个客户端设置多个github账号https方式
git clone https://username:password@git.oschina.net/shenhualxt/NeteaseWeb.git fatal: Authentication failed for ' https://git.oschina.net/shenhualxt/NeteaseWeb.git/'
解决办法一
https://yourname:password@git.oschina.net/name/project.git
解决办法二 :Mac电脑上的钥匙串,每次我们设置好用户名和密码都会自动存储到Mac的钥匙串上面,每次使用命令行上传代码的时候,Mac会自动填充A账号和密码
这时候我只需要打开钥匙串,然后搜索git,把有关oschina的账号密码都删除掉。git clone https://git.oschina.net/shenhualxt111/git_practise.git Cloning into 'git_practise'... Username for 'https://git.oschina.net': Password for 'https://shenhualxt111@git.oschina.net':
为什么要git add 而不直接git commit
类比
add类比购物车
commit类比支付
想想如果没有add 那不是每买一件物品就是付款?
有了购物车我可以一次买好多东西,钱也一次性付完。图示
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。分批提交,降低commit的颗粒度,代码回滚会更容易
git stage a.py c.py git commit -m "function 1" git stage b.py d.py git commit -m "function 2"
分阶段提交,同一个文件分阶段提交
比如,你修改了文件 hello.py,修改了一些以后,做了 git add heello.py动作,相当于对当前的hello.py 做了一个快照, 然后又做了一些修改,这时候,如果直接采用 git commit 递交,则只会对第一次的快照进行递交,当前内容还保存在 working 工作区。- 文件快照,便于回退
做了部分修改以后,进行 git add,然后任何时刻,都可以回退到add时的状态:git checkout – hello.py - git diff , git diff –staged 和 git diff HEAD的差别
当一个文件做了stage,然后又做了一些修改,则:
git diff 显示当前工作区的文件和stage区文件的差异
git diff –staged 显示stage区和HEAD的文件的差异
git diff HEAD 显示工作区和上次递交文件的差异 - 最佳实践:
做了阶段性修改,但是还不能做一次递交,这时先 git stage 一下
如果有问题,可以随时 checkout 回退
递交之前,使用 git status,git diff HEAD 仔细查看是否需要的递交
git commit -a ,保证递交了所有内容
时光穿梭机(版本回退)
对git commit 进行回滚
#回退到上一个版本 git reset --hard HEAD^ #回退到往上n个版本 git reset --hard HEAD~n #回退到指定的版本,通过git log 查看提交历史,获得commit id git reset --hard <commit id>
对回滚进行回滚
好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?
Git提供了一个命令,用来记录你的每一次命令git reflog
git checkout -- file
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。场景一: 修改了workspace文件,没有add,commit ,想直接丢弃workspace的修改
git checkout -- file
场景二:修改了workspace文件,且add到了暂存区,又再修改了该文件,想丢弃add之后的修改git checkout -- file
场景三:修改了workspace文件,且add到了暂存区,想将文件移出暂存区git reset HEAD file
简写git reset
场景四:已提交了不合适的修改到版本库(即不合适的git commit)git reset --hard <commit id>
场景五:git pull 后,回退到git pull之前 待续
场景六:已提交不合适的修改的远程库(即不合适的git push)reset 和 checkout的区别
当文件加入了 stage 区以后,如果要从stage删除,则使用 reset,此时工作区的文件不做任何修改,比如:
git reset hello.py 这个命令就是 git stage hello.py 的反操作。
当文件加入了 stage 区以后,后来又做了一些修改,这时发现后面的修改有问题,想回退到stage的状态,使用 checkout 命令:
git checkout hello.py
提交的不是文件,而是修改(git tracks changes)
- Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
什么时候会pull不下来?
当你本地修改了一个文件,而且该文件被另一个人修改,并push了,那么
➜ /Users/terry/WorkSpace/git练习/git_practise git:(master) ✗ >git pull
Updating 67e4e18..cdbf666 error: Your local changes to the
following files would be overwritten by merge: reset.txt Please,
commit your changes or stash them before you can merge. Aborting
它要求提交或暂存你的修改,这时你可以
1、git add,commit 之后pull;
2、如果你不想为做了一半的工作创建一次commit,则可以git stash(修改的跟踪文件与暂存改动 - 然后将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动。)在pull之后,git stash pop,可能会有冲突。
什么时候修改会丢失,而且再也找不回来?
git checkout -- <file>
会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动 ,即没有git add的修改,都会丢失
-git reset --hard <comment-id>
GIT在某些方面优于SVN的地方
- GIT是分布式的,SVN不是
GIT跟SVN一样有自己的集中式版本库或服务器。但,GIT更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect out代码后会在自己的机器上克隆一个自己的版本库
。可以这样说,不管你有没有网络,你仍然能够提交文件,查看历史版本记录,创建项目分支,回退,给予你最大的灵活性。 - GIT更安全
GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏 - GIT速度更快
在分支管理,查看log上面, - git版本库占用空间小
(几乎是svn的分支数之一也就是说如果有四个分支,svn的版本库的体积将接近git的四倍),SVN每个分支都是一份代码的copy,而git每个分支只是各个提交点的hash值的集合。分支几乎不占用什么空间;
GIT 和SVN的选择
- GIT专门用于源代码管理。
- SVN用于开发文档、二进制程序,大型文件的管理
- 任何事情,归根结底都是人的问题,工具只是工具。
git文件中的三种状态
- Untracked files
在git目录下,创建新的文件,没有任何git操作时的文件状态,可以通过git add 操作,转变为第二种状态 - Changes to be committed
该文件在暂存区域生成了快照,等待被提交。正如Git所提示的那样,通过“git rm –cached filename”命令,可以将文件状态还原为未暂存状态,即回到“Untracked files”文件状态;对该文件进行修改,转变成第三种状态 - Changes not staged for commit
表明文件已经修改,但是还没有放入暂存区域,也就是没生成快照。如果现在进行commit操作,只是将修改之前的文件快照提交到了git目录,一定记住:只有暂存区域的文件(即:文件状态为“Changes to be committed”)才会被提交。正如提示,通过“git add filename”命令将已修改文件更新到暂存区域中,如果想撤销修改,可以使用“git checkout – filename”命令。
什么是HEAD
- 其实git HEAD 变量的内容存储在一个文本文件中: .git/HEAD:
$ cat .git/HEAD
ref: refs/heads/master
- 上面的结果告诉我们需要看看这个文件: refs/heads/master ,它位于 .git 的目录中,它里面存储了 HEAD 指向的内容:
$ cat .git/refs/heads/master
9c65d51b2c8f405debdf9b100505f814981e8940
- HEAD指向当前分支,最近的一次提交