git學習筆記

0. 前言

git在團隊協作中有重要作用,是有必要進行系統學習的一門工具。本篇是筆者學習git操作的備忘筆記,主要在linux上進行。

1. git歷史

很多人都知道,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管理了!牛是怎么定義的呢?大家可以體會一下。
Git迅速成為最流行的分布式版本控制系統,尤其是2008年,GitHub網站上線了,它為開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。
歷史就是這么偶然,如果不是當年BitMover公司威脅Linux社區,可能現在我們就沒有免費而超級好用的Git了。

2. git三大區

git.jpg

git2.png
  • 工作區(The working tree):即電腦中git倉庫所在的目錄,進行工作和修改的目錄。
  • 暫存區(The staging area):暫時存放你的修改的區域。 通過git add命令將工作區改動的內容(包括修改的文件、新增的文件)添加到暫存區。 暫存區是你下次要提交的內容,"that stores information about what will go into your next commit"。
  • 版本庫(The Git directory):是存放git倉庫中各歷史版本的區域,在倉庫所在根目錄的.git/目錄下。 當你執行commit提交時,git會將暫存區的內容復制到版本庫中,并設為最新版本。 當執行clone從遠程克隆倉庫當本地時,會將那個遠程倉庫的版本庫也克隆下來。 在版本庫中,有一個HEAD指針,它指向當前分支(通常是master)的當前版本。

3. git配置

git config --global user.name "yourname" 配置你的名字

git config --global user.email youremail 配置你的郵箱

--global 對當前用戶,--system 對所有用戶

git config --list 查看已有的配置信息

vim ~/.gitconfig 編輯當前用戶的git配置文件,vim /etc/gitconfig 所有用戶的git配置文件

vim .gitignore 倉庫根目錄下的.gitignore文件中配置了git操作時的忽略文件

4. git基礎操作

4.1. 創建本地倉庫

git init 在當前文件夾創建一個可git管理的本地倉庫

4.2. 將工作區保存到暫存區

git add xxx add命令并非添加一個文件。而是,將修改或新增的文件從工作區添加到當前本地倉庫的暫存區中,表明此修改或新增的文件在下次commit提交的內容之中了。常用git add來添加新增的文件。

git add * 將所有修改與新增的文件添加到暫存區。當你在倉庫根目錄下設置了.gitignore文件并配置了忽略文件時,此命令會報錯,如下:

$ git add *
The following paths are ignored by one of your .gitignore files:
ignore.md
Use -f if you really want to add them.
fatal: no files added

如果你強行使用git add -f *命令,則會添加ignore.md文件。但這樣.gitignore文件就沒有意義了,所以不建議使用git add *git add -f *

4.3. 將暫存區提交到版本庫

git commit 將暫存區提交到本地倉庫的版本庫。若存在沒有被git add添加到暫存區的文件,則不會被提交。

-m "xxxx" 后面跟著的為本次提交的說明。git commit時必須使用此選項。

-a 官方解釋:"Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected." 意思大概是:-a工作區中所有進行修改或刪除后的文件都提交到本地倉庫,但新增的文件并不提交。

常用commit -m"aaa" -a直接將更改從工作區提交到版本庫,而不用經過暫存區。

4.4. 撤銷(重置)

git reset --hard 等價于 git reset --hard HEAD 即撤銷工作區和暫存區中的所有修改,重置為版本庫中HEAD指向的當前版本(未被修改的部分)。

而上一個版本就是 HEAD^,上上一個版本就是 HEAD^^,當然往上100個版本寫100個^比較容易數不過來,所以寫成 HEAD~100

或者,你也可以 git reset --hard <commit_id> 直接回溯到某個版本,<commit_id> 指版本號(通過 git log 查看),版本號沒必要寫全,前幾位就可以了,Git會自動去找。

git reset <file>git reset HEAD <file> 撤銷git add到暫存區的修改。

git checkout -- <file> 撤銷工作區的修改。

4.5. 刪除

git rm <file> 如果你已經把某個新增文件提交到版本庫了,然后你想刪除這個文件,那就用該命令將文件刪去,再提交。使用該命令后,git的狀態是:

$ git rm test.md
rm 'test.md'
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    test.md

說明 git rm 會直接更新到暫存區。

刪除文件其實還可以,直接刪除,如下:

$ ls
README.md  ignore2.md  test2.md
$ rm test2.md
$ ls
README.md  ignore2.md
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    test2.md

no changes added to commit (use "git add" and/or "git commit -a")

此時沒有直接更新到暫存區,可以通過 git add/rm <file> 來更新。同時,可以通過 git checkout -- <file> 來恢復這個文件。

4.6. 查看狀態

git status 顯示工作區與暫存區的狀態,比如哪些文件被修改了、哪些文件沒保存到暫存區、哪些文件沒提交等等。若存在沒被add的新文件(即未被git跟蹤的文件),則會提示Untracked

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   .gitignore
#   deleted:    ignore.md
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   test.md
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   ignore2.md

git status -s 更簡單地顯示狀態變化,如:顯示 M controllers/article.go
顯示內容的每一行開頭,M表示被修改、A表示被增加、??表示未受控制

$ git status -s
A  .gitignore
D  ignore.md
M  test.md
?? ignore2.md

4.7. 查看不同

git diff readme.txt 查看readme.txt這個文件中具體什么內容被修改了。其中:

  • git diff 查看工作區和暫存區的區別
  • git diff --cached 查看暫存區和版本庫之間的區別
  • git diff HEAD 查看工作區和版本庫之間的區別

4.8. 查看提交日志

git log 查看倉庫版本庫中(本地倉庫和遠程倉庫的版本庫是一樣的)從最近到最遠的版本信息。換而言之,即每次提交的信息。如下是一次的信息:

commit ee26988de11d36133d180663ddf7b24c4a6233e5
Author: douNine <test@dev3.airdb.io>
Date:   Fri Dec 21 00:47:21 2018 +0800

    modify task/sync_bbs.go

其中commit一項對應的,是git提交的版本號

git log --graph 顯示版本以及分支圖,可以說很生動形象了

git reflog 查看歷史git命令

4.9. 隱藏工作

當工作區的修改未提交,而我們又想將其隱藏起來時,就需要用到git的stash功能。

git stash 隱藏工作區和暫存區的修改,儲存到一個地方。

$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   test2.md

no changes added to commit (use "git add" and/or "git commit -a")
$ git stash
Saved working directory and index state WIP on master: f0f89d4 --no-ff merge
$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

git stash list 查看儲存起來的工作現場。

$ git stash list
stash@{0}: WIP on master: f0f89d4 --no-ff merge

恢復工作現場有兩種方法:

一是用git stash apply恢復,但是恢復后,stash內容并不刪除,你需要用git stash drop來刪除;

另一種方式是用git stash pop,恢復的同時把stash內容也刪了。

5. git分支

5.1. 分支的作用:

分支在實際中有什么用呢?假設你準備開發一個新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由于代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。
現在有了分支,就不用怕了。你創建了一個屬于你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合并到原來的分支上,這樣,既安全,又不影響別人工作。

總而言之,就是你可以在另外的git分支上干自己的事,而不影響主分支。做完還可以更新到主分支上。

注:git中主分支只有一條,叫 master。一條分支就是一條時間線,每個時間節點代表著每個版本。master是主分支的名字,同時也是指向主分支最新節點的指針,而HEAD一開始指向的就是 master 指針。

5.2. 創建、切換分支

git branch dev 創建dev分支。dev分支會繼承master分支的所有內容。

git checkout dev 切換到dev分支上。

git checkout -b dev 創建dev分支,然后切換到dev分支上。git checkout命令加上-b參數表示創建并切換分支,相當于以下兩條命令:

$ git branch dev
$ git checkout dev
Switched to branch 'dev'

5.3. 查看分支

git branch 查看分支,* 后面的是當前所處分支。

$ git branch
* dev
  master

git branch -a 查看遠程和本地所有的分支信息。

git log --graph --pretty=oneline --abbrev-commit 該命令常用于生動形象地顯示簡略的分支圖。顯示如下:

$ git log --graph --pretty=oneline --abbrev-commit
*   07bb2d8 (HEAD -> master, origin/master, origin/HEAD, dev) merge
|\
| * 5a0a7da commit in dev
* | 48a4216 commit in master
|/
* 6aa880e a
*   91147e8 解決分支沖突
|\
| * ea5cf82 commit in dev
* | 28809bb commit in master
|/
* 82016a7 commit in dev
* 6bf1a5d git rm
* 09f2106 bb
* 4524372 aabb
* 058e02c aaa
* f5cc038 git add -f * can add all file including the ignore file
* b5f8f30 aa
* 92c65b1 test add
* d0fe8dc test
* 3a870e8 true demo
* 09d694b find why show falsely
* d6b46e1 also test
* a757718 test.md
* 69483da Update README.md
* cfb9ede Update README.md
*   9bdf268 Merge pull request #1 from 99MyCql/readme-edits
|\
| * 3cef569 Update README.md
|/
* 677f493 Initial commit

5.4. 合并分支

在dev分支上添加一些內容,然后提交到該分支上,如下:

$ git add branch.md
$ git commit -m"commit in dev"
[dev 82016a7] commit in dev
 1 file changed, 1 insertion(+)
 create mode 100644 branch.md
$ git status
On branch dev
nothing to commit, working tree clean

回到主分支上,意料之中,并沒有出現剛剛修改的內容(新增了branch.md文件)。

$ git checkout dev
Switched to branch 'dev'
$ ls
README.md  branch.md  ignore2.md  test2.md
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ ls
README.md  ignore2.md  test2.md

此時,需要將dev分支上合并到master分支上,就能將修改從dev分支更新到master分支上了。

git merge dev 將dev分支合并到master分支。結果如下:

$ git merge dev
Updating 6bf1a5d..82016a7
Fast-forward
 branch.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 branch.md
$ ls
README.md  branch.md  ignore2.md  test2.md

5.5. 合并分支(分支管理篇)

使用 git merge dev 將dev分支合并到master分支時,會將dev中的提交都變為master中的提交。即將兩個分支融合在一起,dev中的提交將不在顯示。這種合并方式稱為:Fast-forward

但在實際使用中,我們希望保留dev的提交信息,這樣能清晰地了解項目每一步的進行。

$ git merge --no-ff -m "xxx" dev 該命令的作用是不采用Fast-forward模式,保留dev分支中每次提交的信息。合并到master分支時,建立一個新的提交,即將dev中的新內容提交到master,而不是粗暴地融合。因此,該命令相當于一個提交,需要附加提交信息-m "xxx"該命令是項目中的合并常用命令

--no-ffFast forward 區別:

未合并時:

      A---B---C dev
     /
    D------------ master

git merge dev 合并:

    D-A---B---C master

git merge --no-ff -m "xxx" dev 合并:

      A---B---C dev
     /         \
    D-----------E master

5.6. 刪除分支

git branch -d dev 刪除dev分支

如果分支未合并,則需要強制刪除 git branch -D dev

5.7. 解決分支合并沖突

在dev分支上修改branch.md文件并提交。然后,切換到master分支上修改branch.md文件同樣位置,但修改內容不同,接著在master上也進行提交。

此時,在master分支上合并dev分支。顯然,兩個分支上都對同一文件同一位置做了不同修改,這樣的合并必然會產生沖突的。合并結果如下:

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

查看branch.md文件,文件中內容如下:

<<<<<<< HEAD
in master branch:
change in master
=======
in dev branch:
add this change
>>>>>>> dev

<<<<<<< HEAD======= 之間的是master分支中的內容。

=======>>>>>>> dev 之間是dev分支中的內容。

對于兩部分沖突內容,我們需要 手動解決沖突 。選擇需要的留下,而將剩下的刪除即可。此處,我們選擇master中的內容。解決后文件內容如下:

in master branch:
change in master

此時再查看git狀態:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   branch.md

no changes added to commit (use "git add" and/or "git commit -a")

按照git的建議,再 git commit -a 提交即可。

1)雖然在master分支中合并了沖突,但是,在dev分支中的內容并沒有被修改。不過,合并之后,dev分支已經不重要了。

2)在沖突未解決時,很多git操作都不能使用,比如:撤銷。

5.8. 分支管理策略

在實際開發中,我們應該按照幾個基本原則進行分支管理:

首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面干活;

那在哪干活呢?dev分支。也就是說,dev分支是不穩定的,到某個時候,比如1.0版本發布時,再把dev分支合并到master上,在master分支發布1.0版本;

你和你的小伙伴們每個人都在dev分支上干活,每個人都有自己的分支,時不時地往dev分支上合并就可以了。

軟件開發中,bug就像家常便飯一樣。有了bug就需要修復,在Git中,由于分支是如此的強大,所以,每個bug都可以通過一個新的臨時分支來修復,修復后,合并分支,然后將臨時分支刪除。

而合并時,注意要采用--no-ff模式。

6. git遠程倉庫

6.1. 克隆到本地

git clone https://github.com/xxx/xxx 將github上xxx遠程倉庫的代碼克隆到本地,形成本地倉庫。

假如,遠程有兩個分支master和dev,本地只有一個master分支,克隆或者拉取后并不會在本地創建dev分支。

我們需要用git checkout -b dev origin/dev命令,將遠程dev分支創建到本地。

$ git clone https://github.com/99MyCql/TestOfGit.git
Cloning into 'TestOfGit'...
remote: Enumerating objects: 53, done.
remote: Counting objects: 100% (53/53), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 84 (delta 20), reused 50 (delta 17), pack-reused 31
Unpacking objects: 100% (84/84), done.
$ cd TestOfGit/
$ ls
branch.md  ignore2.md  README.md  test2.md
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master
$ git checkout -b dev origin/dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'

6.2. 查看遠程倉庫信息

git remote 查看遠程倉庫信息。

git remote -v 查看詳細信息。

$ git remote
origin
$ git remote -v
origin  https://github.com/99MyCql/TestOfGit.git (fetch)
origin  https://github.com/99MyCql/TestOfGit.git (push)

-v 顯示了抓取和推送的地址,如果不可推送則沒有第二個地址。

git branch -a 查看遠程和本地所有的分支信息。

$ git branch -a
* dev
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master

6.3. 添加遠程倉庫

git remote add <name> <url>,添加一個遠程倉庫,shortname為自定義的遠程主機名,url為遠程倉庫的url

6.4. 刪除遠程倉庫

git remote remove <name>

6.5. 本地與遠程分支追蹤關系

在某些場合,Git會自動在本地分支與遠程分支之間,建立一種追蹤關系(tracking)。比如,在git clone的時候,所有本地分支默認與遠程主機的同名分支,建立追蹤關系,也就是說,本地的master分支自動"追蹤"origin/master分支。Git也允許手動建立追蹤關系。

$ git branch --set-upstream-to origin/dev dev 該命令指定dev分支追蹤origin/dev分支,即將本地dev分支與遠程dev分支建立追蹤關系。

當沒有建立追蹤關系時,如果在dev分支進行遠程操作又沒有指定遠程分支時,則會出錯:

$ git branch
* dev
  master
$ git push
fatal: The current branch dev has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin dev

因此,得先建立本地分支與遠程分支的追蹤關系:

$ git branch --set-upstream-to origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
$ git push
Username for 'https://github.com': 99MyCql
Password for 'https://99MyCql@github.com':

6.6. 拉取

$ git pull <遠程主機名> <遠程分支名>:<本地分支名> 取回遠程主機某個分支的更新,再與本地的指定分支合并。

如:
$ git pull origin next:master 取回origin主機的next分支,與本地的master分支合并

$ git pull origin next 如果遠程分支是與當前分支合并,則冒號后面的部分可以省略。

$ git pull origin 本地的當前分支自動與對應的origin主機"追蹤分支"進行合并。

$ git pull 該命令表示,當前分支自動與唯一追蹤分支進行合并。

如果遠程主機刪除了某個分支,默認情況下,git pull 不會在拉取遠程分支的時候,刪除對應的本地分支。這是為了防止,由于其他人操作了遠程主機,導致git pull不知不覺刪除了本地分支。

但是,你可以改變這個行為,加上參數 -p 就會在本地刪除遠程已經刪除的分支。$ git pull -p

6.7. 推送

$ git push <遠程主機名> <本地分支名>:<遠程分支名> 注意,分支推送順序的寫法是<來源地>:<目的地>,所以git pull是<遠程分支>:<本地分支>,而git push是<本地分支>:<遠程分支>。

$ git push origin master 該命令表示,將本地的master分支推送到origin主機的master分支。如果后者不存在,則會被新建。

$ git push origin :master 如果省略本地分支名,則表示刪除指定的遠程分支,因為這等同于推送一個空的本地分支到遠程分支。
等同于:
$ git push origin --delete master 刪除origin主機的master分支。

$ git push origin 將當前分支推送到origin主機的對應存在追蹤關系的分支。

如果當前分支只有一個追蹤分支,那么主機名都可以省略
$ git push

6.6. 解決沖突

當多人協作時,經常會出現沖突。
比如,A和B同時拉取了遠程最新版到本地。A修改了項目的origin.md文件,同時提交并推送到了遠程。B也修改了該文件,但當B要推送時,便出現沖突報錯了:

$ git push
Username for 'https://github.com': 99MyCql
Password for 'https://99MyCql@github.com':
To https://github.com/99MyCql/TestOfGit.git
 ! [rejected]        dev -> dev (fetch first)
error: failed to push some refs to 'https://github.com/99MyCql/TestOfGit.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

顯然,遠程版本庫(A推送后更新了遠程版本庫)和本地版本庫不相同,必然會出現沖突。
此時,我們需按照提示,先拉取最新的內容。

$ git pull
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/99MyCql/TestOfGit
   f7a736f..69d4b68  dev        -> origin/dev
Auto-merging origin.md
CONFLICT (add/add): Merge conflict in origin.md
Automatic merge failed; fix conflicts and then commit the result.

然后,跟解決合并分支沖突一樣,進行手動解決。再將解決后內容提交并推送即可。

$ vim origin.md
$ git status
On branch dev
Your branch and 'origin/dev' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both added:      origin.md

no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m"solve the conflict"
[dev 6cc66a2] solve the conflict
$ git push
Username for 'https://github.com': 99MyCql
Password for 'https://99MyCql@github.com':
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 567 bytes | 51.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To https://github.com/99MyCql/TestOfGit.git
   69d4b68..6cc66a2  dev -> dev

7. 參考教程:

git官網
廖雪峰git教程
阮一峰的網絡日志

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容

  • Git教程 一、Git簡介 1.1. Git的誕生1.2.集中式的vs分布式 二、安裝Git 三、創建版本庫 四、...
    曹淵說創業閱讀 957評論 0 2
  • ----------------- Git 學習 ------------------ Git 簡介 Git...
    Junting閱讀 2,240評論 0 3
  • git學習筆記 聲明 本文是本人學習Git過程中所做的筆記,以便日后查閱,文中多有錯漏之處,不建議用作學習材料,文...
    sayonara_yoyo閱讀 691評論 0 1
  • 一、常用終端指令 $ pwd用于查看當前目錄 $ mkdir learngit 創建一個名為learngit的空目...
    天山雪蓮_38324閱讀 464評論 0 1
  • 畢業后回到家鄉,第一年在私立初中當初一的班主任,一心想證明自己,每天從早晨起來盯早操到上課再到間操,到午...
    娟Taylor閱讀 393評論 0 1