Git学习

本文引用:Git学习

例子

例1:张三和李四需要对图书馆中同一本书,进行修改。

图书馆会将这本书最新修订版本分发给张三和李四。

张三,李四修改完成后送给图书馆。

问题:倘若不存在图书馆,或图书馆无意间被毁了,怎么办?张三和李四无法得知互相修改内容?

image

例2:一本正在编写的书需要张三和李四编写。

张三在自己的书上写了最新内容,李四也在自己的书上写了最新内容。

两个人只需把各自修改的地方告诉对方即可。之后两个人手中的书都是最新内容。

减少了图书馆,也减少很多不确定因素。

image

背景

Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由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 <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变。

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

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

使用

image
  • workspace:工作区

  • staging area:暂存区/缓存区

  • local repository:版本库或本地仓库

  • remote repository:远程仓库

基本使用

命令 说明
git init 初始化仓库
git clone 拷贝一份远程仓库,也就是下载一个项目。。
git add 添加文件到暂存区
git status 查看仓库当前的状态,显示有变更的文件。
git diff 比较文件的不同,即暂存区和工作区的差异。
git commit 提交暂存区到本地仓库。
git rebase 可用于commit压缩(合并多个commit为单个commit)
git reset 回退版本。
git rm 删除工作区文件。
git mv 移动或重命名工作区文件。
git log 查看历史提交记录
git blame <file> 以列表形式查看指定文件的历史修改记录
git remote 远程仓库操作
git fetch 从远程获取代码库
git pull 下载远程代码并合并
git push 上传远程代码并合并
git branch [new branch name] 没有参数时,git branch 会列出你在本地的分支。<br />指定 [new branch name]则会在本地创建新分支
git checkout [-b] (branch name) 执行:git checkout (branch name)时会切换到指定分支。<br />执行:git checkout (new branch name)时会创建新分支并切换到该分支上。
git branch -d (branch name) 删除本地指定分支
git push origin --delete (remote branch name) 删除远程分支,同时也会删除本地分支
git merge (other branch name) 合并分支:将其他分支内容合并当前分支中

使用git --help查看更多命令

  • git初始化:git init # 在一个目录执行,会生成.git目录文件
  • 克隆远程仓库代码到本地:
    • git clone http://xxx# 执行完成后,会在所在目录下生成一个名称为项目名称的目录/文件夹
  • 拉取远程仓库最新代码:
    • git pull # 此步骤更多的是在执行git push前执行,否则可能会提示merge或push失败。
  • 提交文件到远程仓库:假定当前所在分支:main
    • 将文件加到暂存区:git add test.txt
    • 将文件提交到本地仓库:git commit -m "add test.txt file"
    • 推送到远程仓库:git push -u origin main
  • 查看仓库地址
    • git remote -v
  • 查看分支
    • 查看本地分支:git branch
    • 查看所有分支(包含远程分支):git branch -a
  • 删除分支
    • 本地分支:git branch -d (branch name)
    • 远程分支:git push origin -d (branch name)

高级使用

分支合并

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test) ## 当前分支:main分支
$ vi test.txt ## 编辑内容

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ echo "test merge branch" >> merge.txt ## 新增一个merge.txt文件

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ ls
README.md  merge.txt  test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ git add . ## add所有修改到暂存区
warning: LF will be replaced by CRLF in merge.txt.
The file will have its original line endings in your working directory

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ git commit -m "test merge" ## 提交到本地仓库
[test 2af25aa] test merge
 2 files changed, 3 insertions(+)
 create mode 100644 merge.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ git checkout main ## 切换到main分支
Switched to branch 'main'
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main) ## 当前分支:main分支
$ ls ## 此时main分支下只有2个文件
README.md  test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ cat test.txt ## 查看test.txt也没有新内容
test in main branch

test cherry-pick

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git merge test ## 将test分支合并到当前的main分支
CONFLICT (add/add): Merge conflict in test.txt
Auto-merging test.txt
Automatic merge failed; fix conflicts and then commit the result.

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ ls ## 再次查看,发现多了个文件
README.md  merge.txt  test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ cat test.txt ## 再次查看文件内容,发现新增了其他内容。并产生合并冲突
## 1. 之前执行git merge test时已经提示有冲突,关键字:CONFLICT)。
## 2. 从当前分支名称(main|MERGING)也能区分产生冲突
test in main branch

test cherry-pick
<<<<<<< HEAD
=======
============
test branch merge
>>>>>>> test

合并出现分支冲突

合并过程中,出现文件内容冲突问题。
合并时出现CONFLICT字样。

  • 执行合并命令
Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git merge test
CONFLICT (add/add): Merge conflict in test.txt
Auto-merging test.txt
Automatic merge failed; fix conflicts and then commit the result.

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ cat test.txt
test in main branch

test cherry-pick
<<<<<<< HEAD
=======
============
test branch merge
>>>>>>> test
  • 手动修改冲突内容
Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ git diff ## 查看不同
diff --cc test.txt
index 2c9058d,ef3349c..0000000
--- a/test.txt
+++ b/test.txt
@@@ -1,3 -1,5 +1,8 @@@
  test in main branch

  test cherry-pick
++<<<<<<< HEAD
++=======
+ ============
+ test branch merge
++>>>>>>> test

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ vi test.txt ## 编辑冲突文件,解决冲突

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ git diff ## 查看不同
diff --cc test.txt
index 2c9058d,ef3349c..0000000
--- a/test.txt
+++ b/test.txt
@@@ -1,3 -1,5 +1,5 @@@
  test in main branch

  test cherry-pick
 -============
++==================
+ test branch merge
## 以上内容,可以看出删除(“-”减号表示)和新增(“+”减号表示)

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ git status -s ## 检查状态
A  merge.txt
AA test.txt
## 此时AA是红色表示
  • 标记冲突已解决:用 git add 要告诉 Git 文件冲突已经解决
Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ git add test.txt ## add到暂存区,此操作会告知git表示已经解决冲突文件

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ git status -s ## 再次检查状态
A  merge.txt
M  test.txt
## 此时M是绿色表示


Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main|MERGING)
$ git commit ## 执行commit,此时不需要加-m参数。会自动进入另一个窗口。提示输入commit信息
[main 6b431d6] Merge branch 'test' solve conflict

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git push -u origin main ## 推送到远程仓库
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 790 bytes | 263.00 KiB/s, done.
Total 8 (delta 2), reused 0 (delta 0), pack-reused 0
To http://gitlab.adorado.top/gaoqihua/test-parent.git
   5f90207..6b431d6  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

合并单个文件到指定分支

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main) ## 当前分支:main分支
$ ls 
README.md  test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git checkout test
Switched to branch 'test'

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test) ## 当前分支:test分支
$ ls ## 查看文件,此时没有test.txt文件
README.md

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ git checkout main test.txt ## 使用checkout命令,将main分支中根目录下text.txt文件合并过来
Updated 1 path from fefc1a5

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ ls ## 再次查看文件,已经存在了test.txt文件
README.md  test.txt

合并commit

合并单个commit到其他分支

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test) ## 当前分支:test分支
$ git log --oneline
bc82781 (HEAD -> test, origin/test) test cherry-pick ## 在test分支上新提交的内容。将此提交合并到main分支。log id:bc82781
744cf22 merge test
8fc010f Initial commit

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (test)
$ git checkout main ## 切换到main分支
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main) ## 当前分支:main分支
$ git cherry-pick bc82781 ## 执行cherry-pick,指定log id。将指定commit合并到当前分支
[main f4533ec] test cherry-pick
 Date: Mon Feb 28 15:26:42 2022 +0800
 1 file changed, 2 insertions(+)

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ cat test.txt
test in main branch

test cherry-pick

多个commit成一个commit

  • 场景:有时合并分支时,由于分支commit太多,会造成合并后main分支log太多,需要合并分支前先合并commit
$ git log --oneline
4ee51d6 docs(user): update user/README.md
176ba5d docs(user): update user/README.md
5e829f8 docs(user): add README.md for user
f40929f feat(user): add delete user function
fc70a21 feat(user): add create user function
7157e9e docs(docs): append test line 'update3' to README.md
5a26aa2 docs(docs): append test line 'update2' to README.md
55892fa docs(docs): append test line 'update1' to README.md
89651d4 docs(doc): add README.md

可以看到我们提交了 5 个 commit。接下来,我们需要将 feature/user分支的改动合并到 master 分支,但是 5 个 commit 太多了,我们想将这些 commit 合并后再提交到 master 分支。
接着,我们合并所有 commit。在上一步中,我们知道 fc70a21是 feature/user分支的第一个 commit ID,其父 commit ID 是 7157e9e,我们需要将7157e9e之前的所有分支 进行合并,这时我们可以执行:

$ git rebase -i 7157e9e

执行命令后,我们会进入到一个交互界面,在该界面中,我们可以将需要合并的 4 个 commit,都执行 squash 操作,如下图所示:

修改完成后执行:wq 保存,会跳转到一个新的交互页面,在该页面,我们可以编辑 Commit Message,编辑后的内容如下图所示:

开头的行是 git 的注释,我们可以忽略掉,在 rebase 后,这些行将会消失掉。修改完成后执行:wq 保存,就完成了合并提交操作。

除此之外,这里有 2 个点需要我们注意:

  • git rebase -i 这里的一定要是需要合并 commit 中最旧 commit 的父 commit ID。
  • 我们希望将 feature/user 分支的 5 个 commit 合并到一个 commit,在 git rebase 时,需要保证其中最新的一个 commit 是 pick 状态,这样我们才可以将其他 4 个 commit 合并进去。

然后,我们用如下命令来检查 commits 是否成功合并。可以看到,我们成功将 5 个 commit 合并成为了一个 commit:d6b17e0

$ git log --oneline
d6b17e0 feat(user): add user module with all function implements
7157e9e docs(docs): append test line 'update3' to README.md
5a26aa2 docs(docs): append test line 'update2' to README.md
55892fa docs(docs): append test line 'update1' to README.md
89651d4 docs(doc): add README.md

此时,就可以将d6b17e0合并到其他分支即可。

撤销add

撤销所有add

针对add时,不小心将很多文件都add了。需要撤销这些add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ vi test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff ## 编辑完成后使用diff查看不同
diff --git a/test.txt b/test.txt
index 2c9058d..3a91585 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1,5 @@
 test in main branch

 test cherry-pick
+===================================
+test: cancel add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git add test.txt ## 执行add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff ## 执行add后查看不同,显示没有任何不同。说明没有新的修改需要add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git reset head ## 撤销,将整体修改撤销add操作
Unstaged changes after reset:
M       test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff ## 再次查看不同,发现已经恢复到跟之前修改后执行diff结果一样
diff --git a/test.txt b/test.txt
index 2c9058d..3a91585 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1,5 @@
 test in main branch

 test cherry-pick
+===================================
+test: cancel add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$

撤销单个文件

针对add时,不小心包含个别文件,只需要对个人文件撤销add。如果执行git reset head很不划算。

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ vi test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff ## 编辑完成后使用diff查看不同
diff --git a/test.txt b/test.txt
index 2c9058d..3a91585 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1,5 @@
 test in main branch

 test cherry-pick
+===================================
+test: cancel add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git add test.txt ## 执行add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff ## 执行add后查看不同,显示没有任何不同。说明没有新的修改需要add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git reset head test.txt ## 只需要指定撤销的文件即可。
Unstaged changes after reset:
M       test.txt

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff
diff --git a/test.txt b/test.txt
index 2c9058d..3a91585 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1,5 @@
 test in main branch

 test cherry-pick
+===================================
+test: cancel add

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$
  • 如果此时发现该文件不应该被修改,恢复修改前内容。可以执行以下内容:
Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git checkout -- test.txt ## 将文件回滚到上一次操作

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ git diff

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$ cat test.txt
test in main branch

test cherry-pick

Administrator@DESKTOP-G03KTBR MINGW64 /e/ideaWorkSpace/sky/test-parent (main)
$

撤销commit

  • --mixed撤销到add之前的状态

保留 本地仓库暂存区、以及工作区的代码,即回到 git add . 操作之前的状态

  • --soft撤销到add之后,commit之前的状态

保留 暂存区工作区的代码,即回到git commit -m "提交信息" 操作之前、 git add . 操作之后 的状态

  • --hard撤销到修改之前的代码:add之前的修改都会丢失。

不会保留提交的代码,即会造成commit的代码以及工作区的代码丢失,一朝回到解放前,慎用!

  • 假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本
  • git fetch origin
  • git reset --hard origin/main

忽略文件

推送时,防止临时文件或IDE产生的文件被提交到git远程仓库

  • 使用.gitignore文件
    • 在项目根目录下创建.gitignore文件
    • 将需要忽略的文件名称填写到该文件即可
  • 示例:
## 忽略项目跟目录下target目录
target/

## 忽略扩展名为log的文件
**.log

## 忽略文件名包含关键字的文件
*mvn*

## 指定忽略文件
### 忽略根目录下files子目录下aa目录下的test.txt。此时如果aa目录还有其他文件,则会被提交到git远程仓库
files/aa/test.txt

标签

像其他版本控制系统(VCS)一样,Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)
可以用此功能标记项目版本问题。

  • 查看所有tag:git tag
  • 创建标签:git tag -a [tag name] -m [tag message]
    • 例如:git tag -a v1.0 -m "my version 1.0"
  • 查看标签信息:git show v1.0# 就会显示标签信息,创建时间等

特别时,新功能发布,多个bug修复时最好创建标签。

分支管理

  • main:主分支,在gitlab/github上创建新项目时自动生成分支
  • dev:开发分支
  • fat(Feature Acceptance Test Environment: 功能验收测试环境):测试环境分支
  • uat(User Acceptance Test Environment: 用户验收测试环境):用于生产环境下软件测试使用(环境跟生产保持一致)
  • hotfix: 紧急问题修复。
    • 针对生产环境出现紧急问题进行修复。基于main分支拉取hotfix分支进行紧急问题修复;
  • feature/devX: 新需求开发分支。
    • 当有新需求时,基于dev分支创建feature/devX分支
    • 该分支也有自己的日常新需求验证环境,新需求开发完成,会将该分支代码合并回主开发分支dev上,经fat测试完成后实现交付。

参考:
Git的诞生
Git 工作区、暂存区和版本库 [菜鸟教程]
Git基本操作 [菜鸟教程]
git cherry-pick 教程 [阮一峰的网络日志]
git 合并多个commit
Git撤销已经提交的 commit
Git工作流的分支管理的解决方案
Git 基础 - 打标签
Git 分支 - 分支管理
分布式 Git - 分布式工作流程

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容