git操作
版本控制
集中式(svn)
优点:- 代码存放在单一的服务器上,便于项目的管理
- svn因为每次存的都是差异,需要的硬盘空间会相对小一点 可是回滚的速度会很慢
- 服务器宕机:员工写的代码得不到保障
- 服务器炸了:整个项目的历史记录都会丢失
分布式(git)
- git每次存的都是项目的完整快照 需要的硬盘空间会相对大一点(git团队对代码做了极致的压缩,最终需要的时机空间比svn多不了太多 可是git的回滚速度极快 )
- 优点:完全的分布式
- 缺点:命令多
安装git之后初始化
查看版本git —version
初始化配置
git config --global user.name “username” git config --global user.email xxxxxxxx.com 查看初始配置的结果 git config --list 创建一个文件夹,作为工作区, 进入工作区cd /Users/shuchenhao/Desktop/workspace
使用git init命令初始化git仓库workspace % git init
显示隐藏文件夹shift + command+.相关linux命令
查看当前目录下的文件ls -l
查看当前目录以及子目录下的文件包括文件夹
find ./
查看当前目录以及子目录的文件不包括文件夹
find ./ -type f
创建文件
touch file.txt
删除文件
rm file.txt
修改文件名称
mv 111/file1.txt file2.txt
给文件写入内容
echo '123'> 111/file2.txt
查看文件内容
cat file2.txt
进入文件写入模式
vim 111/file2.txt
i:进入写模式
esc:进入命令状态
q!强制退出
wq:保存退出
set nu:设置行号
区域
流程:工作区=》暂存区=〉版本库 工作区 暂存区 版本库对象
Git对象(代表文件的一次次版本)
向数据库写入内容,并返回对应键值对echo 'test content' |git hash-object -w --stdin
-w 选项指示 hash-object命令存储数据对象;若不指定此选项,则该命令仅返回对应的键值 —stdin选项则指示该命令从标准输入读取内容:若不指定此项,则须在命令的尾部给出待存储文件的路径 根据键值对拉去数据git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
-p 选项可指示该命令自动的判断内容的类型,并为我们显示格式友好的内容
对一个文件进行版本控制
echo 'version 1’>test.txt
git hash-object -w test.txt
问题:
记住文件的每一个版本所对应的SHA-1值并不现实
在git中,文件名并没有背保存,而是仅保存了文件的内容
解决方法:树对象
注意:当前的操作都是在对本地数据库进行操作,不涉及暂存区
树对象(代表项目的一次次版本)
查看暂存区当前的样子 git ls-files -s 将文件加入暂存区git update-index --add --cacheinfo 100644 4871fd52755be519c29ae719f385bd5f2863627c test.txt
将暂存区做成快照
生成树对象
git write-tree
提交对象
以上内容完全为了理解其原理,所涉及命令不需记的高层命令
git操作最基本的流程
创建工作目录 对工作目录进行修改 git add ./ (一般是路径,./代表工作目录下的所有改变)- git hash-object -w 文件名(修改了多少个工作目录中的文件 此命令就要背执行多少次)
- git update-index….
- git write-tree
- git commit-tree
git高层命令
git init 初始化仓库 git status 查看文件状态 git diff 查看哪些修改还没有暂存 git diff —staged 查看哪些已被暂存还未被提交的 git log —online 查看提交的历史记录 git add ./ 将修改添加到暂存区 git rm 文件名 删除工作目录对应的文件 再修改添加到暂存区 git mv 原文件名 新文件名 将工作目录中的文件进行重命名 再将修改添加到暂存区 git commit git commit -a 跳过暂存区 git commit -a -m 注释 将暂存区提交到版本库git分支操作(杀手功能)
分支的本质其实就是一个提交对象 HEAD: 是一个指针,它默认指向master分支 切换分支时其实就是让HEAD指向不同的分支 每次有新的提交时 HEAD都会带着当前指向的分支 一起往前移动 git branch 显示分支列表 git branch 分支名 创建分支 git checkout 分支名 切换分支 git branch -D 分支名 强制删除分支 查看历史记录 git log —oneline —decoraete —graph —all切换分支
最佳实践:每次切换分支前,当前分支一定得是干净的(他已提交状态) 坑:- 在切换分支时 如果有未暂存的修改 (第一次),或者有未提交的暂存(第一次)
- 分支可以切换成功,但这种操作可能会污染其他分支
合并
快速合并 git merge 分支名 典型合并 解决冲突 git add ./存储
git stash 将未完成的修改保存到一个栈上 git stash apply 你可以在任何时候重新应用这些改动 git stash list 查看存储 git stash apply stash@{2} 如果不指定一个储藏,git指定的为栈顶 git stash drop 加上要移除的储藏的名字来移除 git stash pop 来应用储藏然后立即从栈上扔掉它后悔药
工作区- 如何撤回在工作目录中的修改
- git checkout — filename
- 如何撤回自己的暂存
- git reset HEAD filename
- 如何撤回自己的提交
- 注释写错
- git commit —amend
reset
git log : git relog :主要是HEAD变化,那么就会记录下来 三部曲- 第一部:soft
- git reset -soft HEAD~===(—amend)
- 只动HEAD,带着分支一起移动
- 第二部:git reset —mixed HEAD ~
- 动HEAD(带着分支一起移动)
- 动了暂存区
- 第三部:hard
- git reset —hard HEAD~
- 动HEAD(带着分支一起移动)
- 动了暂存区
- 动了工作目录
checkout
git checkout commithash & git reset —hard commithash- checkout只动HEAD而且带着分支一起走
- checkout对工作目录是安全的 —hard是强制覆盖工作目录
路径reset
git reset [—mixed] HEAD filename (加文件名指定撤销某个文件的路径,不加,撤销全部) 简写: git reset filename 动了暂存区数据恢复
git branch recover-branch hash值打tag
git tag v1.0 git tag v1.0 b18dcdd 删除标签git tag -d v1.0
实战
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 901ff1b (HEAD -> master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout -b #53
Switched to a new branch '#53'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 901ff1b (HEAD -> #53, master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout master
Switched to branch 'master'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 901ff1b (HEAD -> master, #53) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git branch -d #53
Deleted branch #53 (was 901ff1b).
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout -b iss53
Switched to a new branch 'iss53'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 901ff1b (HEAD -> iss53, master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % ls -l
total 8
-rw-r--r-- 1 shuchenhao staff 18 5 25 11:59 a.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % echo "iss53 50%">iss53.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % ls -l
total 16
-rw-r--r-- 1 shuchenhao staff 18 5 25 11:59 a.txt
-rw-r--r-- 1 shuchenhao staff 10 5 25 12:04 iss53.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git add ./
shuchenhao@shuchenhaodeMacBook-Air workspace % git commit -m "1 commit for iss53 v1"
[iss53 3af9d1f] 1 commit for iss53 v1
1 file changed, 1 insertion(+)
create mode 100644 iss53.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch iss53
nothing to commit, working tree clean
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3af9d1f (HEAD -> iss53) 1 commit for iss53 v1
* 901ff1b (master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout master
Switched to branch 'master'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3af9d1f (iss53) 1 commit for iss53 v1
* 901ff1b (HEAD -> master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout -b hotbug
Switched to a new branch 'hotbug'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3af9d1f (iss53) 1 commit for iss53 v1
* 901ff1b (HEAD -> hotbug, master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % vim a.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git commit -a -m "3 commit for a.txt v3 to fix hotbug"
[hotbug a2f6693] 3 commit for a.txt v3 to fix hotbug
1 file changed, 1 insertion(+)
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch hotbug
nothing to commit, working tree clean
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* a2f6693 (HEAD -> hotbug) 3 commit for a.txt v3 to fix hotbug
| * 3af9d1f (iss53) 1 commit for iss53 v1
|/
* 901ff1b (master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout master
Switched to branch 'master'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* a2f6693 (hotbug) 3 commit for a.txt v3 to fix hotbug
| * 3af9d1f (iss53) 1 commit for iss53 v1
|/
* 901ff1b (HEAD -> master) 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git merge hotbug
Updating 901ff1b..a2f6693
Fast-forward
a.txt | 1 +
1 file changed, 1 insertion(+)
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* a2f6693 (HEAD -> master, hotbug) 3 commit for a.txt v3 to fix hotbug
| * 3af9d1f (iss53) 1 commit for iss53 v1
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git branch -d hotbug
Deleted branch hotbug (was a2f6693).
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* a2f6693 (HEAD -> master) 3 commit for a.txt v3 to fix hotbug
| * 3af9d1f (iss53) 1 commit for iss53 v1
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch master
nothing to commit, working tree clean
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout iss53
Switched to branch 'iss53'
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch iss53
nothing to commit, working tree clean
shuchenhao@shuchenhaodeMacBook-Air workspace % vim iss53.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* a2f6693 (master) 3 commit for a.txt v3 to fix hotbug
| * 3af9d1f (HEAD -> iss53) 1 commit for iss53 v1
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % vim iss53.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch iss53
Changes not staged for commit:
(use "git add
(use "git restore
modified: iss53.txt
no changes added to commit (use "git add" and/or "git commit -a")
shuchenhao@shuchenhaodeMacBook-Air workspace % git commit -a -m "2 commit for iss53.txt v2 100%"
[iss53 39b1928] 2 commit for iss53.txt v2 100%
1 file changed, 1 insertion(+)
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 39b1928 (HEAD -> iss53) 2 commit for iss53.txt v2 100%
* 3af9d1f 1 commit for iss53 v1
| * a2f6693 (master) 3 commit for a.txt v3 to fix hotbug
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch iss53
nothing to commit, working tree clean
shuchenhao@shuchenhaodeMacBook-Air workspace % cat a.txt
a.txt v1
a.txt v2
shuchenhao@shuchenhaodeMacBook-Air workspace % vim a.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git commit -a -m "3 commit for iss53 to patch a.txt=v3 to real 100%"
[iss53 3930d75] 3 commit for iss53 to patch a.txt=v3 to real 100%
1 file changed, 1 insertion(+)
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3930d75 (HEAD -> iss53) 3 commit for iss53 to patch a.txt=v3 to real 100%
* 39b1928 2 commit for iss53.txt v2 100%
* 3af9d1f 1 commit for iss53 v1
| * a2f6693 (master) 3 commit for a.txt v3 to fix hotbug
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git checkout master
Switched to branch 'master'
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3930d75 (iss53) 3 commit for iss53 to patch a.txt=v3 to real 100%
* 39b1928 2 commit for iss53.txt v2 100%
* 3af9d1f 1 commit for iss53 v1
| * a2f6693 (HEAD -> master) 3 commit for a.txt v3 to fix hotbug
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git merge iss53
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
shuchenhao@shuchenhaodeMacBook-Air workspace % cat a.txt
a.txt v1
a.txt v2
<<<<<<< HEAD
a.txt v3
=======
a.txt v3 for iss53
>>>>>>> iss53
shuchenhao@shuchenhaodeMacBook-Air workspace % vim a.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % cat a.txt
a.txt v1
a.txt v2
a.txt v3 for hotbug
a.txt v3 for iss53
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Changes to be committed:
new file: iss53.txt
Unmerged paths:
(use "git add
both modified: a.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git add./
git: 'add./' is not a git command. See 'git --help'.
shuchenhao@shuchenhaodeMacBook-Air workspace % git add ./
shuchenhao@shuchenhaodeMacBook-Air workspace % git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: a.txt
new file: iss53.txt
shuchenhao@shuchenhaodeMacBook-Air workspace % git commit -m "4 commit for fix cliect"
[master 3712fd1] 4 commit for fix cliect
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3712fd1 (HEAD -> master) 4 commit for fix cliect
|\
| * 3930d75 (iss53) 3 commit for iss53 to patch a.txt=v3 to real 100%
| * 39b1928 2 commit for iss53.txt v2 100%
| * 3af9d1f 1 commit for iss53 v1
* | a2f6693 3 commit for a.txt v3 to fix hotbug
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace % git branch -d iss53
Deleted branch iss53 (was 3930d75).
shuchenhao@shuchenhaodeMacBook-Air workspace % allbranch
* 3712fd1 (HEAD -> master) 4 commit for fix cliect
|\
| * 3930d75 3 commit for iss53 to patch a.txt=v3 to real 100%
| * 39b1928 2 commit for iss53.txt v2 100%
| * 3af9d1f 1 commit for iss53 v1
* | a2f6693 3 commit for a.txt v3 to fix hotbug
|/
* 901ff1b 2 commit for a.txt v2
* f2edf9e .DS_Store
* b18dcdd 1 commit for a.txt v1
shuchenhao@shuchenhaodeMacBook-Air workspace %
远程分支 远程跟踪分支 本地分支 正常的数据推动和拉去步骤 确保本地分支已经跟踪了远程跟踪分支 拉去数据:git pull 上传数据 git push
一个本地分支怎么去跟踪一个远程跟踪分支
当克隆的时候会自动生成一个master本地分支(已经跟踪了对应的远程跟踪分支)
在新建其他分支时 可以指定想要跟踪的远程跟踪分支
git checkout -b 本地分支名 远程跟踪分支名
git checkout —track 远程跟踪分支名
将一个已经存在的本地分支 改成一个跟踪分支
git branch -u 远程跟踪分支名
团队协作
- 项目经理初始化远程仓库
- 一定要初始化一个空的仓库,在github上操作
- 项目经理创建本地仓库
- git init
- 将源码复制进来
- 修改用户名和邮箱
- git add
- git commit
- 项目经理推送本地仓库到远程仓库
- git push 别名 分支 (输入用户名和密码,推完之后生成一个远程跟踪分支)
- 项目经理邀请成员,成员接收邀请
- 在github上操作
- 成员克隆远程仓库
- git clone 仓库地址(在本地生成.git文件 默认为远程仓库配置了别名origin)
- 默认主分支有对应的远程跟踪分支
- 只有在克隆时 本地分支master和远程跟踪分支 别名/master 是有同步关系的
- 成员做出贡献
- 修改源码文件
- git add
- git commit
- git push 别名 分支名(输入用户名和密码)
- 项目经理更新修改
- git fetch 别名(将修改同步到远程跟踪分支上)
- git merge 远程跟踪分支
冲突
git本地操作会不会有冲突 典型合并的时候 git远程协作的时候 会不会有冲突 push pull远程协作
本地分支 远程跟踪分支 远程分支 远程协作基本流程 第一步:项目经理创建一个空的远程仓库 第二步:项目经理创建一个待推送的本地仓库 第三步:为远程仓库配别名,配完用户名和邮箱 第四步:在本地仓库中初始化代码 提交代码 第五步:推送 第六步:邀请成员 第七步:成员克隆远程仓库 第八步:成员做出修改 第九步:成员推送自己的修改 第十步:项目经理拉去成员的修改 做跟踪 克隆仓库时, 自动会为master做跟踪 本地没有分支 git checkout —track 远程跟踪分支(remote/分支名) 本地已经有分支 git branch -u 远程跟踪分支(remote/分支名) 推送: git push [别名] [分支名] 拉去 git pull git fetch 别名 :合并远程跟踪分支 pull request- 让第三方人员使用仓库