Git安裝
- 地址:https://git-scm.com/downloads
- 下載對應(yīng)平臺的git版本安裝即可
Git配置
配置快捷命令
- 在用戶根目錄下(如C:/user/Administrator)新建配置文件命名為.gitconfig
- 將以下內(nèi)容寫入文件
[user]
email = xxx(郵箱如:foxleezh@gmail.com)
name = xxx(名字如:foxleezh)
[alias]
st = status
ci = commit
br = branch
co = checkout
glog = log --pretty=oneline
pus = push
pul = !git pull --rebase && git submodule update --init --recursive
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
[merge]
tool = vim
[core]
packedGitLimit = 512m
packedGitWindowSize = 512m
[pack]
deltaCacheSize = 2047m
packSizeLimit = 2047m
windowMemory = 2047m
配置ssh
- 在命令行輸入
ssh-keygen -t rsa
- 在用戶目錄(如C:/user/Administrator)打開.ssh文件夾,查看id_rsa.pub文件魄揉,將密鑰拷貝到服務(wù)器密鑰庫
配置忽略文件
- 將.gitignore文件放置到項目根目錄下
# OSX
*.DS_Store
# Gradle files
build/
build_out/
obj/
.gradle/
*/build/
captures/
gradle/
# IDEA
*.iml
.idea/.name
.idea/encodings.xml
.idea/inspectionProfiles/Project_Default.xml
.idea/inspectionProfiles/profiles_settings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/vcs.xml
.idea/workspace.xml
.idea/libraries
.idea/runConfigurations.xml
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/gradle.xml
.idea/
# Built application files
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Local configuration file (sdk path, etc)
local.properties
# Log Files
*.log
# Special
gradle.properties
- 凡是在列表中的文件(*表示所有)都將被git忽略剪侮,對這些文件的任何改動,git都不會追蹤
- 但是有時我們只想追蹤某幾個文件洛退,其它都忽略瓣俯,可以如下配置,兵怯!后面的內(nèi)容為追蹤的文件
/*
!.gitignore
!README.md
Git使用
- 命令行使用(windows打開git bash , mac 打開終端)
- Git bash是命令行工具彩匕,內(nèi)部使用linux指令集(linux使用文件另附)
- 更多l(xiāng)inux命令http://www.php100.com/html/webkaifa/Linux/2009/1106/3485.html
一.準(zhǔn)備工作
- 新建倉庫(進(jìn)入到項目的根目錄下)
git init
- 添加忽略規(guī)則,將.gitignore文件放置到根目錄下
- 添加文件媒区,將需要管理的文件加入到根目錄下
二.代碼管理
- 查看狀態(tài)
git st
紅色表示已修改未保存到緩存區(qū)驼仪,綠色表示已保存到緩存區(qū)
Git有三個狀態(tài),一是修改未保存到緩存驻仅,二是保存到緩存谅畅,三是提交到版本庫
我們可以對比著word文檔來學(xué)習(xí),狀態(tài)一就相當(dāng)于你在word中修改了一些東西噪服,但是沒有按ctrl+s鍵保存起來毡泻,狀態(tài)二就是你修改了東西后按了ctrl+s,暫時存起來了粘优,狀態(tài)三就是點(diǎn)擊了另存為仇味,將它另外存放起來了
- 保存到緩存區(qū)
git add 文件路徑(添加單個文件到緩存)
一開始修改了homepage和loading兩個文件,git st后顯示紅色
使用git add后,將homepage加入到緩存區(qū)
git st后,發(fā)現(xiàn)homepage變?yōu)榫G色
git add -u(添加所有修改到緩存)
一開始修改了homepage和loading兩個文件帅霜,git st后顯示紅色
使用git add -u后彩届,將homepage和loading一起加入到緩存區(qū)
git st后,發(fā)現(xiàn)homepage和loading變?yōu)榫G色
git add . (添加所有文件到緩存鲤妥,包括新建的文件)
此用法與git add -u類似,區(qū)別在于,git add -u只能將修改的文件加入緩存王财,如果該文件是新建的,要使用git add .裕便, 這個“.”符號表示所有
- 撤銷緩存區(qū)的文件
git reset 文件路徑(撤銷單個文件)
首先git st后發(fā)現(xiàn)绒净,有兩個已經(jīng)加入到緩存區(qū)的homepage和loading文件
使用git reset homepage后,將homepage文件撤銷
git st后發(fā)現(xiàn)偿衰,homepage變?yōu)榧t色
git reset(撤銷所有緩存區(qū)的文件)
首先git st后發(fā)現(xiàn)挂疆,有兩個已經(jīng)加入到緩存區(qū)的homepage和loading文件
使用git reset后改览,將所有文件撤銷
git st后發(fā)現(xiàn),homepage和loading都變?yōu)榧t色
- 撤銷修改
git co 文件路徑(撤銷單個文件的修改)
首先使用git st缤言,發(fā)現(xiàn)有homepage和loading兩個文件被修改
使用git co homepage宝当,撤銷homepage的修改
git st后發(fā)現(xiàn)homepage文件不見了,查看原代碼墨闲,代碼中的修改也沒有了
git reset --hard (撤銷所有文件的修改)
首先使用git st今妄,發(fā)現(xiàn)有homepage和loading兩個文件被修改
使用git reset --hard,撤銷所有的修改
git st后發(fā)現(xiàn)homepage和loading文件不見了,顯示nothing to commit,working directory clean鸳碧, 這表示當(dāng)前沒有任何的修改
- 查看修改的內(nèi)容
git diff 文件路徑(查看單個文件修改)
首先使用git st,有兩個文件Homepage,loading被修改
使用git diff homepage,可以看到哪些被修改了盾鳞,按箭頭上下可以翻動,”-”號表示刪除(紅色顯示)瞻离,”+”號表示添加(紅色顯示)
查看完成后輸入q腾仅,即可退出查看
要查看所有修改直接用git diff
git diff --cached (查看處于緩存區(qū)的修改)
首先使用git st,有兩個文件Homepage,loading被加入到緩存區(qū)
使用git diff homepage,可以看到哪些被修改了,按箭頭上下可以翻動套利,”-”號表示刪除(紅色顯示)推励,”+”號表示添加(紅色顯示)
查看完成后輸入q,即可退出查看
要查看所有修改直接用git diff --cached
- 將緩存區(qū)的內(nèi)容提交到版本庫
git ci -m “我修改了什么”
首先git st,發(fā)現(xiàn)有兩個文件homepage和loading加入到緩存區(qū)
使用git ci -m “注釋”肉迫,將緩存區(qū)的內(nèi)容提交到版本庫验辞,這里注釋是隨便寫的,用于提示該commit修改了一些什么內(nèi)容
git st后發(fā)現(xiàn)喊衫,緩存區(qū)中的內(nèi)容不見了跌造,這是因?yàn)橐呀?jīng)提交到版本庫中了
- 查看版本庫中的內(nèi)容
git log
git log后發(fā)現(xiàn)有兩個提交,“我修改了什么”是剛剛提交的commit族购,下面來分析下:
commit ac76744b1843665d0c6cf1add7cf758bc824c89a (這行是一個md5值壳贪,用來唯一標(biāo)識commit的)
Author: foxleezh foxleezh@gmail.com (這行是說明該commit是誰提交的)
Date: Fri Jul 10 10:02:16 2015 +0800 (提交的時間)
我修改了什么 (之前我們寫的注釋)
- 查看某個提交中修改的內(nèi)容
git show commit號
git show ac76744b, 這個ac76744b就是之前git log時對應(yīng)的md5值,可以只取前6位
查看完成用q退出
我們回顧一下已講的內(nèi)容寝杖,一般來說使用流程都是
- 修改了一些內(nèi)容违施,用git st看看狀態(tài)
- git diff看看修改了哪些內(nèi)容
- 確認(rèn)無誤后,將需要提交的內(nèi)容git add加入到緩存區(qū)
- git ci -m 加入到版本庫中瑟幕,這里說一下磕蒲,平常我們都用git ci -m新建一個commit,其實(shí)通常我們不用新建commit只盹,而是用git ci --amend追加的方式
這里我們修改了loading中的內(nèi)容亿卤,然后git add -u 加入到緩存區(qū),因?yàn)槲覀冎皇切薷牧撕苌俚膬?nèi)容鹿霸,不需要重新提交commit,所以使用git ci --amend追加到之前的commit秆乳,這時會讓我們修改注釋內(nèi)容
這是一個vim的編輯器懦鼠,之前l(fā)inux中有講钻哩,按i進(jìn)入編輯模式,箭頭移動光標(biāo)就可以修改注釋肛冶,修改好后街氢,按ESC進(jìn)入一般模式,按:進(jìn)入命令模式睦袖,輸入wq珊肃,保存退出
git log后發(fā)現(xiàn)沒有新建commit,只是追加到了之前的commit
我們在使用的過程中可能要回到某一個提交馅笙,這時可以使用git reset命令伦乔,這個命令可以帶參數(shù),--mixed(回到修改未保存狀態(tài)),--soft(回到緩存區(qū)狀態(tài)),--hard(刪除所有修改)董习,默認(rèn)是--mixed
先講講--hard烈和,這個好理解,就是把這個commit之后的所有修改都刪除
這里有四個commit
我們先使用git reset --hard 皿淋,將“我修改了名字”之后的所有修改的刪除
git st后發(fā)現(xiàn)招刹,沒有任何修改
git log后,已經(jīng)回到”我修改了名字”的commit
下面我們試試git reset --mixed或者git reset
git log我們會發(fā)現(xiàn)--mixed和--hard都回到了“我修改了名字”的版本窝趣,區(qū)別在于git st后--mixed將“測試reset1”和“測試reset2”中修改的內(nèi)容保留下來了疯暑,這樣好處在于,我們有時回到某一個commit不是要刪除所有的修改哑舒,而是只想改變某一些東西妇拯,這時我們把需要改的地方改掉后,再重新提交一個commit散址,這樣會方便很多
最后我們試試git reset --soft
這個跟git reset --mixed差不多乖阵,只是它是把之后的修改放入了緩存區(qū)
三.分支操作
之前我們的操作都是同一個分支上的操作,現(xiàn)在我們引入分支的概念
- 查看分支
git br
git默認(rèn)都會有一個分支叫master预麸,這個分支叫主分支瞪浸,一般來說我們提交代碼的時候是用這個分支來提交,但是實(shí)質(zhì)上它跟普通的分支沒有什么區(qū)別
為什么我們要引入分支吏祸,svn也有分支的概念对蒲,但是基本是在服務(wù)器端,我們本地基本是在一個分支上修改內(nèi)容的贡翘,然后commit蹈矮,有時我們改一個東西A可能需要很長時間,當(dāng)還沒有改完卻突然要修改另外一個東西B鸣驱,而且A因?yàn)闆]有改完不能合并到版本庫泛鸟,這時svn就有點(diǎn)乏力了,我們可能要把之前沒改完的東西A刪除掉踊东,然后再來改接下來的B北滥。
git因?yàn)槭欠植际降母詹伲还苁欠?wù)器端還是本地,都可以存在很多分支再芋,這樣就方便我們利用分支很好地管理代碼菊霜,當(dāng)我們修改任務(wù)A的時候,我們可以在分支A上修改济赎,分支A在master的基礎(chǔ)上新建而來鉴逞,當(dāng)我們還沒有處理完A就要處理B時,我們可以新建另一個分支B司训,也是在master的基礎(chǔ)上新建而來构捡,這樣當(dāng)我們處理完B,提交后豁遭,可以回到A叭喜,繼續(xù)我們之前的開發(fā),當(dāng)我們開發(fā)完A蓖谢,要提交的時候捂蕴,我們把B的內(nèi)容整合進(jìn)來,這個涉及到分支合并闪幽,我們之后再講
- 新建分支
git co -b TEST //新建名為TEST的分支啥辨,當(dāng)前的分支會以綠色顯示
當(dāng)我們新建分支時,是從當(dāng)前分支的基礎(chǔ)上新建的盯腌,新建的分支保留了當(dāng)前分支所有的修改溉知,所以新建分支相當(dāng)于對當(dāng)前分支的一份拷貝,而不是一個空的分支
- 切換分支
git co master //切換到master分支
- 刪除分支
git br -D TEST //D大寫腕够,表示強(qiáng)制刪除
-
分支合并
講合并级乍,我們就回到之前那個例子,我們處理A任務(wù)和B任務(wù)都新建一個分支分別為TESTA和TESTB帚湘,這兩個分支都是在master的基礎(chǔ)上新建過來的
這里有三個分支玫荣,分別是master,TESTA,TESTB
主分支master有兩個提交
git co TESTA切換到TESTA,上面有三個提交,在master基礎(chǔ)上多了一個“測試A”的提交
git co TESTB切換到TESTB,上面有三個提交大诸,在master基礎(chǔ)上多了一個“修改B”的提交
現(xiàn)在我們需要把A和B合并到一起
首先切換到TESTA分支捅厂,然后使用git rebase TESTB命令,將TESTB合并到TESTA前面
一般來說资柔,如果兩個分支沒有沖突的話焙贷,合并就完成了,像上圖有沖突就需要解決沖突
git st后發(fā)現(xiàn)贿堰,TESTA和TESTB都修改了loading文件
git diff loading后辙芍,查看具體的沖突內(nèi)容,git用特殊的符號標(biāo)記沖突羹与,<<<<<< HEAD到=======之前是你要合并的分支對當(dāng)前文件的修改沸手,因?yàn)楝F(xiàn)在我是要把TESTB合并到TESTA外遇,所以HEAD就代表TESTB的修改,也就是“我是用來追加的B”是TESTB的修改契吉,然后======與>>>>>>之前的內(nèi)容是TESTA的修改,也就是“我是用來追加的A”這句話
現(xiàn)在我們要做的就是確認(rèn)好是保留A的內(nèi)容诡渴,還是保留B的內(nèi)容捐晶,還是A和B的內(nèi)容都保留,我們修改可以用linux的vim工具來修改妄辩,也可以直接在Android studio或者xcode中修改惑灵,修改時先將<<<<<,======這些特殊標(biāo)記符號去掉眼耀,然后再進(jìn)行修改
修改完成后英支,git add -u 將修改的內(nèi)容加入到緩存區(qū)
然后git rebase --continue,繼續(xù)rebase操作
如果要放棄合并,使用git rebase --abort
合并完成后git log哮伟,我們可以看到干花,TESTB的修改“修改B”已經(jīng)合并進(jìn)TESTA了,這時TESTA分支中就包含了A和B的修改
四.與遠(yuǎn)程服務(wù)器交互
- 生成rsa密鑰
ssh-keygen -t rsa
查看id_rsa.pub文件楞黄,將密鑰拷貝到服務(wù)器密鑰庫
- 從遠(yuǎn)程復(fù)制倉庫
git clone 服務(wù)器倉庫地址
一般來說是新建一個空目錄池凄,然后去克隆服務(wù)器的git倉庫
- 在服務(wù)器添加倉庫
1.新建本地倉庫
git init
2.添加遠(yuǎn)程倉庫地址
git remote add origin ssh://****@****:29418/foxleezh/test.git
3.提交遠(yuǎn)程倉庫
git push origin master
4.切換到遠(yuǎn)程分支
git br -r 查看遠(yuǎn)程分支
git co 切換到某一個遠(yuǎn)程分支
5.刪除遠(yuǎn)程分支
git push origin :branch
6.拉取服務(wù)器分支并切換到臨時分支
git fetch origin branchname && git co FETCH_HEAD
如:
git fetch origin GIT && git co FETCH_HEAD
7.拉取服務(wù)器分支并合并到master
git pull
pull命令相當(dāng)于fetch命令加上merge命令,將服務(wù)器master分支的內(nèi)容拉下來并合并到本地master
git pull --rebase
以rebase形式拉取鬼廓,相當(dāng)于fetch命令加上rebase命令
如果是pull其他分支肿仑,加上分支名
git pull origin branchA
8.向服務(wù)器提交分支
git push
如果是push其他分支,加上分支名
git pull origin branchA
9.常見錯誤
- unable to rewind rpc post data - try increasing http.postBuffer
git config http.postBuffer 524288000
- 高版本不支持ssl
Host www.xxx.com(改成服務(wù)器地址)
HostkeyAlgorithms ssh-dss
五.子模組
- 新建子模組
1.新建父項目碎税、子項目并上傳服務(wù)器
2.克隆父項目尤慰、子項目到不同目錄
git clone ssh://<username>@<hostname>:29418/project-1.git
git clone ssh://<username>@<hostname>:29418/lib1.git
git clone ssh://<username>@<hostname>:29418/lib2.git
3.將子項目變?yōu)楦疙椖康淖幽=M
git submodule add ssh://<username>@<hostname>:29418/lib1.git libs/lib1(這里目錄可以自由更改)
git submodule add ssh://<username>@<hostname>:29418/lib2.git libs/lib2
4.將父項目修改的修改提交服務(wù)器
git add -u
git push
至此,子模組新建完成
- 修改子模組
1.進(jìn)入子模組目錄提交并上傳
git add -u
git push
2.進(jìn)入父項目提交并上傳
git add -u
git push
- 克隆子模組
1.克隆父項目
git clone --recursive ssh://<username>@<hostname>:29418/project-1.git
2.切換子項目分支
到子目錄下(此時分支處于游離狀態(tài))
git co -b newBranch
- 更新子模組
1.在父目錄下更新
git pull
git submodule update
2.切換子項目分支
此時分支處于游離狀態(tài)
git co -b newBranch
- 刪除子模塊(分4步走)
1.根據(jù)路徑刪除子模塊的記錄
$ git rm --cached [path]
2.編輯“.gitmodules”文件雷蹂,將子模塊的相關(guān)配置節(jié)點(diǎn)刪除掉
清理子模塊配置
3.編輯“ .git/config”文件伟端,將子模塊的相關(guān)配置節(jié)點(diǎn)刪除掉
清理子模塊配置
4.手動刪除子模塊殘留的目錄
清理臟文件
六、其他
- Git找回commit
git reflog
-
開發(fā)流程(以master為例)
- 在master的基礎(chǔ)上新建一個分支進(jìn)行修改
git co -b newbranch
- 在新的newbranch上改好代碼后commit
git add -u
git ci -m "newbranch的修改"
- 切換到master上拉取最新代碼萎河,防止別人上傳了代碼自己卻沒有更新
git co master
git pull origin master
- 如果服務(wù)器有代碼更新荔泳,切換回newbranch合并服務(wù)器新增代碼(如果沒有更新,直接執(zhí)行第5步)
git co newbranch
git rebase master
- 切換到master虐杯,合并newbranch代碼
git co master
git rebase newbranch
- 提交代碼到服務(wù)器
git push origin master
- 在master的基礎(chǔ)上新建一個分支進(jìn)行修改
-
有關(guān)git rebase的常識
- 對于rebase的順序
比如 上例中newbranch和master兩個分支的合并
一開始兩分支commit都是1玛歌,2,3
后來newbranch提交了一個4擎椰,commit就是1,2,3,4的順序
而master拉取服務(wù)器更新了5支子,commit就是1,2达舒,3值朋,5的順序
這時我們切換到newbranch叹侄,去rebase master,即git rebase master
rebase后的順序是1,2,3,5,4
如果我們當(dāng)初是切換到master昨登,去rebase newbranch
rebase后的順序是1,2,3,4,5
這里的法則就是趾代,去rebase哪個分支,就把哪個分支塞在下面
- 對于rebase沖突的解決
當(dāng)我們rebase后丰辣,看見有沖突撒强,git st后可以看到?jīng)_突的文件
我們通過Android studio找到?jīng)_突的文件,去搜索=====或者<<<<<<這些特殊標(biāo)記就會找到?jīng)_突的代碼
修改沖突的代碼為你想要的代碼后笙什,記得將=====飘哨,<<<<<這些特殊符號去掉
修改好后git add -u,將修改的代碼提交到緩沖區(qū)
git rebase --continue繼續(xù)rebase,這樣就將沖突解決了
如果rebase過程中想取消琐凭,git rebase --abort
- 能過rebase刪除某幾個commit
比如newbranch上的commit為1芽隆,2,3统屈,4
這時我想將中間的2和3去掉胚吁,變?yōu)?,4
我們首先要將2和3的commit號記下鸿吆,比如是commit2,commit3
然后git rebase --onto commit2空格commit3(commit2后面的是前一個的意思囤采,這個符號在鍵盤的數(shù)字6上面)
其實(shí)可以是git rebase --onto commit1空格commit3(因?yàn)閏ommit2^就是commit1)
- 對于rebase的順序
-
一些Linux常用命令
tab 補(bǔ)全命令
ctrl+c 停止執(zhí)行
- 文件管理
pwd 打印當(dāng)前目錄
cd 進(jìn)入某個目錄
cd /home/develop 進(jìn)入絕對路徑
cd eclipse 進(jìn)入相對路徑
cd ../ 返回上一級目錄touch [file name]打開或創(chuàng)建一個文件
mkdir -p [dir name] 創(chuàng)建一個目錄 -p為強(qiáng)制創(chuàng)建
rm -r [file name/dir name] 刪除一個文件或目錄
ls -al 列出所有文件(包括隱藏文件)的詳細(xì)信息
-d 只列出該目錄的信息cp -rd [目標(biāo)文件] [目的文件] 復(fù)制文件
-r是允許目錄cp
-d是在拷貝軟連接時只拷貝軟連接,如果不加則會把原文件一起拷過去
cp -rd test.txt dir/test.txtmv -i [目標(biāo)文件] [目的文件] 移動文件
-i是詢問是否覆蓋同名文件惩淳,如果[目標(biāo)文件][目的文件]相同蕉毯,那就是重命名find [dn] [參數(shù)]
如:find $HOME -name 'foxlee' -o -type f -o -size +20M
-atime +n :訪問或執(zhí)行時間大于n天的文件
-ctime +n :寫入、更改inode屬性(例如更改所有者思犁、權(quán)限或者連接)時間大于n天的文件
-mtime +n :寫入時間大于n天的文件
文件的 Access time代虾,atime 是在讀取文件或者執(zhí)行文件時更改的。
文件的 Modified time激蹲,mtime 是在寫入文件時隨文件內(nèi)容的更改而更改的棉磨。
文件的 Create time,ctime 是在寫入文件学辱、更改所有者乘瓤、權(quán)限或鏈接設(shè)置時隨 Inode 的內(nèi)容更改而更改的。
因此策泣,更改文件的內(nèi)容即會更改 mtime 和 ctime衙傀,
但是文件的 ctime 可能會在 mtime
未發(fā)生任何變化時更改,例如萨咕,更改了文件的權(quán)限统抬,但是文件內(nèi)容沒有變化。
這里講一下ls中顯示的時間
ls -lc filename 列出文件的 ctime
ls -lu filename 列出文件的 atime
ls -l filename 列出文件的 mtime
繼續(xù)講find的參數(shù)
-name 'filename' 直接查找該文件名的文件(注意加引號)
-type type :通過文件類型查找 type 包含了 f, b, c, d, l, s 等等
d 表示該文件為目錄;
f 表示該文件為普通文件聪建;
b 表示該文件為塊設(shè)備文件钙畔,比如磁盤分區(qū)
l 表示該文件為連接文件(linux file),上邊提到的軟連接即為該類型;
c 表示該文件為串行端口設(shè)備金麸,例如鍵盤擎析、鼠標(biāo)。
s 表示該文件為套接字文件(socket)钱骂,用于進(jìn)程間通信叔锐。
- 文件查看與編輯
vim [fn] 編輯文件 有三種模式(一般模式,編輯模式见秽,命令模式),可以自由切換
一般模式下移動光標(biāo)(esc回到一般模式)
箭頭上下左右一般模式下查找與替換
/word 向光標(biāo)之后尋找一個字符串名為word的字符串讨盒,當(dāng)找到第一個word后解取,按”n”繼續(xù)搜后一個,"N"前一個一般模式下刪除、復(fù)制粘貼
dd 刪除光標(biāo)所在的那一行
yy 復(fù)制光標(biāo)所在的那行
p,P p復(fù)制的數(shù)據(jù)從光標(biāo)下一行粘貼返顺,P則從光標(biāo)上一行粘貼
u 還原過去的操作進(jìn)入編輯模式(按i進(jìn)入)
i 在當(dāng)前字符前插入字符命令模式(按:進(jìn)入)
:q! 不管編輯或未編輯都不保存退出
:wq 保存禀苦,退出
:e! 將文檔還原成最原始狀態(tài)
:set nu 在每行的行首顯示行號
:set nonu 取消行號
- 文件管理