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 commit -m “注释内容”
  •  git write-tree
  • git commit-tree
先将文件放到版本库,再从版本库放入暂存区,一个文件对应一个git对象
 

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
 

切换分支

最佳实践:每次切换分支前,当前分支一定得是干净的(他已提交状态)
坑:
  • 在切换分支时 如果有未暂存的修改 (第一次),或者有未提交的暂存(第一次)
  • 分支可以切换成功,但这种操作可能会污染其他分支
动三个地方
HEAD
暂存区
工作目录
版本库只会无限变多

合并

快速合并
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(带着分支一起移动)
  • 动了暂存区
  • 动了工作目录
 
这与改变HEAD自身不同(checkout所做),
 

checkout

git checkout commithash & git reset —hard commithash
  1. checkout只动HEAD而且带着分支一起走
  2. checkout对工作目录是安全的 —hard是强制覆盖工作目录
git checkout commithash
git checkout —filename
相比于git reset —hard commithash —filename
第一步第二步都没做
只动了工作目录
git checkout commithash file
将会跳过第一步
更新暂存区
更新工作目录
 
 

路径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 -> #53master) 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 -> iss53master) 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 -> hotbugmaster) 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 -> masterhotbug) 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 <file>..." to update what will be committed)

  (use "git restore <file>..." to discard changes in working directory)

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 <file>..." to mark resolution)

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 远程跟踪分支名
 

团队协作

  1. 项目经理初始化远程仓库
  • 一定要初始化一个空的仓库,在github上操作
  1. 项目经理创建本地仓库
  • git init
  • 将源码复制进来
  • 修改用户名和邮箱
  • git add
  • git commit
  1. 项目经理推送本地仓库到远程仓库
  • git push 别名 分支 (输入用户名和密码,推完之后生成一个远程跟踪分支)
  1. 项目经理邀请成员,成员接收邀请
  • 在github上操作
  1. 成员克隆远程仓库
  • git clone 仓库地址(在本地生成.git文件 默认为远程仓库配置了别名origin)
  • 默认主分支有对应的远程跟踪分支
  • 只有在克隆时 本地分支master和远程跟踪分支 别名/master 是有同步关系的
  1. 成员做出贡献
  • 修改源码文件
  • git add
  • git commit
  • git push 别名 分支名(输入用户名和密码)
  1. 项目经理更新修改
  • 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
  1. 让第三方人员使用仓库

常用命令

git status
git add
git commit
git pull
git push
 
 
posted @ 2022-05-26 18:33  终究还是避免不了遗憾  阅读(74)  评论(0编辑  收藏  举报