git核心分支

git的分支是十分的轻量级,git的新建分支,合并分支等操作几乎是瞬间完成。
1、Git 创建一个新的分支仅仅是创建一个新的分支指针。如:git branch testing 创建一个testing分支;会commit 对象上新建一个分支指针并指向当前commit
2、Git 是如何知道当前在哪个分支上工作的呢?有一个名为HEAD 的特别指针,运行git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中,所以当前我们仍然在master分支。
3、要切换到其他分支,执行git checkout 命令。我们现在转换到新建的testing 分支:git checkout testing,git仅仅是将HEAD指针指向了testing,几乎瞬间完成。
4、如果这时我们再次修改了文件,并提交(git commit ),仅仅是testing分支指向了最新commit ,而master仍指向在原来的commit
5、使用git checkout master切换回master分支。git做了两件事它把HEAD 指针移回到master 分支,并把工作目录中的文件换成了master 分支所指向的快照内容。
注意:在git中新的commit对象中的parent是指向着上一个commit。
6、在master分支我们修改文件再进行提交,这时项目提交历史产生了分叉。
Git 中的分支实际上仅是一个包含所指对象校验和(40 个字符长度SHA-1 字串)的文件,所以创建和销毁一个分支就变得非常廉价。新建一个分支就是向一个文件写入41 个字节(外加一个换行符)。
如果我们有需要我们可以完全再次checkout到testing分支去开发新的功能。我们可以在分支间随意切换,并且都是瞬间切换完成。这和之前大多数版本控制系统形成了鲜明对比,它们管理分支大多采取备份所有项目文件到特定目录的方式,所以根据项目文件数量和大小不同,可能花费的时间也会有相当大的差别,快则几秒,慢则数分钟。而Git 的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。每次提交时都记录了祖先信息(译注:即parent 对象),所以以后要合并分支时,寻找恰当的合并基础(译注:即共同祖先)的工作其实已经完成了一大半。

Git 中commit、tree、blob三个对象之间的关系

在现有的项目中查看Commit、tree、blob


进入到有git管理的项目所在的磁盘目录下:
执行git log查看版本提交历史:
每个commit都对应唯一的编号
来看上边执行到最后的冒号:这时该怎么退出再次进入书写git命令呢,  直接输一个 q 就可以了
查看就近commit具体的内容:
git cat-file -p 82cfe8
看到了这个commit中有个tree
接着看下这个tree的具体内容:
git cat-file -p 56c3567

对应磁盘中:
没显示的都是被忽略的文件
tree中又包括tree和blob
查看blob的具体内容,也就是上图中 .gitignore的内容
对应磁盘目录下该文件的内容是一模一样的
至此commit、tree、和blob三者之间的关系也就一目了然了。
1.commit存储一次提交的信息,包括所在的tree,parent是谁,以及提交的作者是谁等信息。
2.tag:标签,给重要的commit的一个别名。
3.tree:代表的是目录结构,或者简单理解为代表一个目录
4.blob:用来存储文件内容,或者说表示一个文件

总结
每一次commit对应一个tree,这个tree又记录了整个文档的目录结构,文件的每一次修改又会生成一个blob,blob信息记录在tree下面。

电脑总是弹出SohuNews.exe应用

弹出sohunews.exe应用程序错误的方法一:机智删除

  1、找到搜狗拼音输入法的安装目录,默认的安装目录在c盘的program files→sougoupinyin→7.0.0.9604(这个是版本号,可能不同)。
  2、在这个文件夹里可以发现一个叫sohunews.exe的东西,删掉它。
  3、为了防止它再次出现,新建一个文件夹,并命名为sohunews.exe。系统是不允许文件和文件夹重名的,所以这个东西就不会再出现。可以到回收站里试着还原一下那个文件,可以看到如图弹窗就成功了

弹出sohunews.exe应用程序错误的方法二:暴力卸载
  1、卸载搜狗拼音输入法,简单粗暴但很有效!换其他什么输入法都行。

从一个git仓库拷贝到另一个git仓库

利用git从一个仓库拷贝一个项目到另一个仓库,并且log也能够一起过去。

1、从原地址克隆一份裸版本库,比如原本托管于 GitHub。
git clone –bare http://github….(原始仓库地址)

2、进入克隆下来的目录
cd project.git(project即为你的项目名称)

3、以镜像推送的方式上传代码到新的仓库地址。
git push –mirror http://…(目标仓库地址)

Git切换到指定的提交(commit)

方法一,新分支
1.1Git查找commitId

$git log
commit cbcf45ec166eee4ca0ade2dc78f1445f7d39f0ab

1.2 检出提交

git checkout cbcf45ec166e
检查提交到新的分支
git checkout -b old-state cbcf45ec166e
-b参数会为提交新建一个分支。

方法二,回滚
git reset –hard 046bd7b5c1d134b8123f59ea71b19875a6a2fc3e

git切换到某个tag

git clone 整个仓库后使用,以下命令就可以取得该 tag 对应的代码了。

git checkout tag_name
但是,这时候 git 可能会提示你当前处于一个“detached HEAD” 状态。

因为 tag 相当于是一个快照,是不能更改它的代码的。

如果要在 tag 代码的基础上做修改,你需要一个分支:

git checkout -b branch_name tag_name
这样会从 tag 创建一个分支,然后就和普通的 git 操作一样了。

如果项目上有一个后来新建的分支test,并且使用

git branch -a
看不到该远程分支:

* develop
remotes/composer/develop
remotes/composer/feature/194
remotes/composer/feature/198
remotes/composer/feature/199
remotes/composer/feature/200
remotes/composer/master
remotes/origin/HEAD -> origin/develop
remotes/origin/develop
remotes/origin/feature/194
remotes/origin/feature/198
remotes/origin/feature/199
remotes/origin/feature/200
remotes/origin/master
直接使用命令git checkout test,出现以下错误

error: pathspec ‘origin/XXX’ did not match any file(s) known to git.
项目上有一个分支test,使用git branch -a看不到该远程分支,直接使用命令git checkout test报错如下:
解决方法是:

1、执行命令git fetch取回所有分支的更新

2、执行git branch -a可以看到test分支(已经更新分支信息)

3、切换分支git checkout test

git结合TortoiseGit使用sshkey,无需输入账号和密码

1 找到TortoiseGit自带的Puttygen工具
2 打开之后,选择Generate(生成的过程中记得移动鼠标)
putty key generator
3生成完毕之后,将上面的公钥设置到github上面
github的设置界面,有sshkeys,添加进去就可以了
4 保存一下私钥到本地
保存之前,先设置一个私钥的密码【上面的passphrase】
5将私钥加到远端设置中
remote:名字
URL:git@172.16.20.27:/git/data/sample.git
putty key 上述生成的Key

Git 分支管理

几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。

有人把 Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来。

创建分支命令
git branch (branchname)

切换分支命令:
git checkout (branchname)
当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录。

合并分支命令:
git merge (branchname)
你可以多次合并到统一分支, 也可以选择在合并之后直接删除被并入的分支。

开始前我们先创建一个测试目录:

$ mkdir gitdemo
$ cd gitdemo/
$ git init
Initialized empty Git repository…
$ touch README
$ git add README
$ git commit -m ‘第一次版本提交’
[master (root-commit) 3b58100] 第一次版本提交
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README
Git 分支管理
列出分支
列出分支基本命令:

git branch
没有参数时,git branch 会列出你在本地的分支。

$ git branch
* master
此例的意思就是,我们有一个叫做 master 的分支,并且该分支是当前分支。

当你执行 git init 的时候,默认情况下 Git 就会为你创建 master 分支。

如果我们要手动创建一个分支。执行 git branch (branchname) 即可。

$ git branch testing
$ git branch
* master
testing
现在我们可以看到,有了一个新分支 testing。

当你以此方式在上次提交更新之后创建了新分支,如果后来又有更新提交, 然后又切换到了 testing 分支,Git 将还原你的工作目录到你创建分支时候的样子。

接下来我们将演示如何切换分支,我们用 git checkout (branch) 切换到我们要修改的分支。

$ ls
README
$ echo ‘runoob.com’ > test.txt
$ git add .
$ git commit -m ‘add test.txt’
[master 3e92c19] add test.txt
1 file changed, 1 insertion(+)
create mode 100644 test.txt
$ ls
README test.txt
$ git checkout testing
Switched to branch ‘testing’
$ ls
README
当我们切换到 testing 分支的时候,我们添加的新文件 test.txt 被移除了。切换回 master 分支的时候,它们有重新出现了。

$ git checkout master
Switched to branch ‘master’
$ ls
README test.txt
我们也可以使用 git checkout -b (branchname) 命令来创建新分支并立即切换到该分支下,从而在该分支中操作。

$ git checkout -b newtest
Switched to a new branch ‘newtest’
$ git rm test.txt
rm ‘test.txt’
$ ls
README
$ touch runoob.php
$ git add .
$ git commit -am ‘removed test.txt、add runoob.php’
[newtest c1501a2] removed test.txt、add runoob.php
2 files changed, 1 deletion(-)
create mode 100644 runoob.php
delete mode 100644 test.txt
$ ls
README runoob.php
$ git checkout master
Switched to branch ‘master’
$ ls
README test.txt
如你所见,我们创建了一个分支,在该分支的上移除了一些文件 test.txt,并添加了 runoob.php 文件,然后切换回我们的主分支,删除的 test.txt 文件又回来了,且新增加的 runoob.php 不存在主分支中。

使用分支将工作切分开来,从而让我们能够在不同开发环境中做事,并来回切换。

删除分支
删除分支命令:

git branch -d (branchname)
例如我们要删除 testing 分支:

$ git branch
* master
testing
$ git branch -d testing
Deleted branch testing (was 85fc7e7).
$ git branch
* master
分支合并
一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。 你可以使用以下命令将任何分支合并到当前分支中去:

git merge
$ git branch
* master
newtest
$ ls
README test.txt
$ git merge newtest
Updating 3e92c19..c1501a2
Fast-forward
runoob.php | 0
test.txt | 1 –
2 files changed, 1 deletion(-)
create mode 100644 runoob.php
delete mode 100644 test.txt
$ ls
README runoob.php
以上实例中我们将 newtest 分支合并到主分支去,test.txt 文件被删除。

合并完后就可以删除分支:

$ git branch -d newtest
Deleted branch newtest (was c1501a2).
删除后, 就只剩下 master 分支了:

$ git branch
* master
合并冲突
合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改。

$ git branch
* master
$ cat runoob.php
首先,我们创建一个叫做 change_site 的分支,切换过去,我们将 runoob.php 内容改为:


创建 change_site 分支:

$ git checkout -b change_site
Switched to a new branch ‘change_site’
$ vim runoob.php
$ head -3 runoob.php

$ git commit -am ‘changed the runoob.php’
[change_site 7774248] changed the runoob.php
1 file changed, 3 insertions(+)

将修改的内容提交到 change_site 分支中。 现在,假如切换回 master 分支我们可以看内容恢复到我们修改前的(空文件,没有代码),我们再次修改 runoob.php 文件。

$ git checkout master
Switched to branch ‘master’
$ cat runoob.php
$ vim runoob.php # 修改内容如下
$ cat runoob.php

$ git diff
diff –git a/runoob.php b/runoob.php
index e69de29..ac60739 100644
— a/runoob.php
+++ b/runoob.php
@@ -0,0 +1,3 @@
+
$ git commit -am ‘修改代码’
[master c68142b] 修改代码
1 file changed, 3 insertions(+)
现在这些改变已经记录到我的 “master” 分支了。接下来我们将 “change_site” 分支合并过来。

$ git merge change_site
Auto-merging runoob.php
CONFLICT (content): Merge conflict in runoob.php
Automatic merge failed; fix conflicts and then commit the result.

$ cat runoob.php # 代开文件,看到冲突内容
<<<<<<< HEAD echo 1; ======= echo ‘runoob’; >>>>>>> change_site
?>
我们将前一个分支合并到 master 分支,一个合并冲突就出现了,接下来我们需要手动去修改它。

$ vim runoob.php
$ cat runoob.php

$ git diff
diff –cc runoob.php
index ac60739,b63d7d7..0000000
— a/runoob.php
+++ b/runoob.php
@@@ -1,3 -1,3 +1,4 @@@

在 Git 中,我们可以用 git add 要告诉 Git 文件冲突已经解决

$ git status -s
UU runoob.php
$ git add runoob.php
$ git status -s
M runoob.php
$ git commit
[master 88afe0e] Merge branch ‘change_site’
现在我们成功解决了合并中的冲突,并提交了结果。

Git 工作区、暂存区和版本库

基本概念
我们先来理解下Git 工作区、暂存区和版本库概念

工作区:就是你在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在 “.git目录下” 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage, index),标记为 “master” 的是 master 分支所代表的目录树。

图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个”游标”。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。

当对工作区修改(或新增)的文件执行 “git add” 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

当执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行 “git rm –cached ” 命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行 “git checkout .” 或者 “git checkout — ” 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

当执行 “git checkout HEAD .” 或者 “git checkout HEAD ” 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。