分区 工作区:仓库目录 版本库:.git
隐藏目录 暂存区:存放在版本库中,叫stage或index
git add
命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit
就可以一次性把暂存区的所有修改提交到分支,然后Stage就空了。
可以想象成,工作区的文件、stage中的文件和分支中的文件是3个独立的文件。
1 [工作区] --(add)-> [版本库: stage --(commit)-> master分支]
日常操作 1 2 3 4 5 6 7 git init # Git管理仓库初始化 git add xxx.xx #添加文件 git add --all # git add -A git commit -m "xx" # 添加 commit git status # 查看状态 git diff xxx.xx # 查看文件变化 git diff HEAD -- xxx.xx # 查看工作区和版本库里面最新版本的区别
回到过去 git log
显示提交日志 会输出每个版本的 commit id。
HEAD
指针指向当前版本,有多少个^
就表示前多少个版本,或者用~N
指定前N个版本,HEAD^^^
和HEAD~3
等价。
1 2 git reset --hard HEAD^ git reset --hard 111ax
退回到旧版本,无法再查看新版本的 commit id,因此需要git reflog
查看最近的操作(reflog: 引用日志,可以查看所有分支的所有引起HEAD指针变动的操作),记下Commit ID,--hard
后面可接Commit ID的前几位,git会自动匹配。
丢弃修改 在commit之前,使用git status
会提示如何撤销修改,使用git restore <file>
或者git resotre --staged <file>
。对于只在工作区的情况,用前者直接丢弃工作区。对于进入暂存区stage的情况,用后者只是将文件移出暂存区,还需要再次restore才能复原。
删记录 1 2 3 4 5 6 git checkout --orphan latest_branch # 切换新分支 git add -A # 缓存所有文件(除.gitignore中的) git commit -am "xxx" # 提交跟踪过的文件 git branch -D master # 删除master分支 git branch -m master # 重命名当前分支为master git push -f origin master # 提交到远程master分支
Github远程仓库 首次执行:
1 2 3 git config --global user.name "Nickname" git config --global user.email "Email@em.com" # git config --global core.quotepath false (显示中文问题)
生成并查看SSH:
1 2 3 ssh-keygen -t rsa -C "Email@em.com" cat ~/.ssh/id_rsa.pub # ls ~/.ssh/ -- id_rsa是私钥,id_rsa.pub是公钥
将公钥添加到Github/Gitee即可使用
添加远程仓库:
1 2 3 4 git remote add Repository_Name Git_Address git push -u Repository_Name master # 第一次推送到远程的空仓库 以后不需要-u指令 git remote -v # 查看远程仓库 git remote rm Repository_Name # 删除
分支 主分支即master
分支,HEAD
指向master
分支指向提交
,可以有其他分支,其他分支也指向提交
,HEAD
可以指向这些分支。
1 2 3 4 5 master ↓ ⬜ → ⬜ → ⬜ → ⬜ ↑ Dev ← HEAD
1 2 3 4 5 6 7 git checkout -b dev # 从*当前分支*中创建分支dev,-b 参数表示创建并切换 或者git switch -c <name> git branch # 查看当前分支 # ... 一些操作 完成开发 git checkout master # 切换回到master 或者git switch <name> git merge dev # 把dev分支的工作成果合并到当前分支(master) git log --graph --oneline # 简要显示log分支图 git branch -d dev # 删除dev分支
分支管理 合并分支时,如果可能,Git会用Fast forward
模式,这样删除分支后,会丢掉分支信息。禁用Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。用merge
合并dev分支时,附上--no-ff
,和-m "xxx"
即可。
1 git merge --no-ff -m "merge with no-ff" dev
master
仅用来发布新版本,每个人都有自己的分支,并且时不时地往dev
分支上合并。
如果工作区有文件,或者已经添加到stage,但是没有在分区内部,那么切换到不同分支之后,工作区或者stage中的这个文件并不会被移动或者变化,只有已经添加到分区内部的文件会变化 。
master
和dev
分支需要远程同步;bug分支只用于在本地修复bug,没必要推到远程。feature
分支是否推到远程,取决于是否多人在开发。
BUG分支 正在dev上的工作未完成,需要临时修bug。先储存现场,再在master上修复bug。由于master和dev上都存在bug,此时可用git cherry-pick
复制一个特定的提交到当前分支。
以下测试中,master中有文件a和b,dev基于master再添加了文件c(未commit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 git add -A # 储存前需要放入stage git stash # 储存现场 # 下面修复master分支的bug git checkout master # 去master,准备在master中创建分支 git checkout -b bug-01 # do something, add, commit 输出commit id : 0f39c70git checkout master # 回去master 准备把bug分支合并到master git merge --no-ff -m "merged bug fix 01" bug-01 git log --graph --oneline # 输出 # * 41ccef2 (HEAD -> master) merged bug fix 01 # |\ # |/ # * cff1bad (dev) add b # * 52621ca add a # master修复完毕,复制修改到dev分支 git checkout dev git cherry-pick 0f39c70 # 0f39c70是修复bug之后的commit id git log --graph --oneline # 输出 # * dfc9722 (HEAD -> dev) fix bug in a # * cff1bad add b # * 52621ca add a # 修复bug完成,下面回dev干活 git checkout dev git stash list # 查看储存的现场 输出:stash@{0}: WIP on dev: f52c633 add merge git stash apply # 恢复 但stash内容不删除 git stash pop # 恢复 同时把stash内容删了 # 也可以 git stash apply stash@{0} 指定不同的stash git checkout master git merge dev git log --graph --oneline # 输出 # * afc0842 (HEAD -> master) Merge branch 'dev' # |\ # | * dfc9722 fix bug in a # * | 41ccef2 merged bug fix 01 # |\ \ # |/| # | * 0f39c70 fix bug in a # |/ # * cff1bad add b # * 52621ca add a git rebase dev git log --graph --oneline # * daa4e1f (HEAD -> master, dev) add c # * dfc9722 fix bug in a # * cff1bad add b # * 52621ca add a
多人协作 多人协作修改了同一个文件,需要先pull下来,在本地处理完毕再push。Git会在有冲突的文件处作出标记,这时候就需要手动修改,然后再尝试下一步操作(push)。
1 2 3 4 5 6 7 8 # PC A git checkout -b dev origin/dev # **创建远程的dev分支**,是在本地创建和远程分支对应的分支 # git add commit and push ... # PC B git pull # 直接pull可能会失败,自然会有提示 git branch --set-upstream-to=origin/dev dev # 指定本地dev分支与远程origin/dev分支的链接 git pull # 再次尝试,然后修改文件冲突,再次push
执行git push --set-upstream origin dev
,也就是说把本地分支与远端的dev分支关联在了一起,关联后,不用每次都git push origin dev
, git pull origin dev
而已。
其他 Push失败解决方案
备份本地文件,再pull下来手动融合文件,然后看一下status,git add -A
一遍过,在commit -m,最后再push一遍。
强行push (使用-f)