




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
Git詳解之Git基礎(chǔ)在工作目錄中初始化新倉庫從現(xiàn)有倉庫克隆檢查當(dāng)前文件狀態(tài)跟蹤新文件暫存已修改文件忽略某些文件查看已暫存和未暫存的更新提交更新跳過使用暫存區(qū)域移除文件移動文件限制輸出長度使用圖形化工具查閱提交歷史修改最后一次提交取消已經(jīng)暫存的文件取消對文件的修改查看當(dāng)前的遠程庫添加遠程倉庫從遠程倉庫抓取數(shù)據(jù)推送數(shù)據(jù)到遠程倉庫查看遠程倉庫信息遠程倉庫的刪除和重命名列顯已有的標簽新建標簽含附注的標簽簽署標簽輕量級標簽驗證標簽后期加注標簽分享標簽自動完成Git命令別名Git基礎(chǔ)讀完本章你就能上手使用Git了。本章將介紹幾個最基本的,也是最常用的Git命令,以后絕大多數(shù)時間里用到的也就是這幾個命令。讀完本章,你就能初始化一個新的代碼倉庫,做一些適當(dāng)配置;開始或停止跟蹤某些文件;暫存或提交某些更新。我們還會展示如何讓Git忽略某些文件,或是名稱符合特定模式的文件;如何既快且容易地撤消犯下的小錯誤;如何瀏覽項目的更新歷史,查看某兩次更新之間的差異;以及如何從遠程倉庫拉數(shù)據(jù)下來或者推數(shù)據(jù)上去。2.1
取得項目的Git倉庫有兩種取得Git項目倉庫的方法。第一種是在現(xiàn)存的目錄下,通過導(dǎo)入所有文件來創(chuàng)建新的Git倉庫。第二種是從已有的Git倉庫克隆出一個新的鏡像倉庫來。在工作目錄中初始化新倉庫要對現(xiàn)有的某個項目開始用Git管理,只需到此項目所在的目錄,執(zhí)行:$gitinit初始化后,在當(dāng)前目錄下會出現(xiàn)一個名為.git的目錄,所有Git需要的數(shù)據(jù)和資源都存放在這個目錄中。不過目前,僅僅是按照既有的結(jié)構(gòu)框架初始化好了里邊所有的文件和目錄,但我們還沒有開始跟蹤管理項目中的任何一個文件。(在第九章我們會詳細說明剛才創(chuàng)建的.git目錄中究竟有哪些文件,以及都起些什么作用。)如果當(dāng)前目錄下有幾個文件想要納入版本控制,需要先用gitadd命令告訴Git開始對這些文件進行跟蹤,然后提交:$gitadd*.c$gitaddREADME$gitcommit-m'initialprojectversion'稍后我們再逐一解釋每條命令的意思。不過現(xiàn)在,你已經(jīng)得到了一個實際維護著若干文件的Git倉庫。從現(xiàn)有倉庫克隆如果想對某個開源項目出一份力,可以先把該項目的Git倉庫復(fù)制一份出來,這就需要用到gitclone命令。如果你熟悉其他的VCS比如Subversion,你可能已經(jīng)注意到這里使用的是clone而不是checkout。這是個非常重要的差別,Git收取的是項目歷史的所有數(shù)據(jù)(每一個文件的每一個版本),服務(wù)器上有的數(shù)據(jù)克隆之后本地也都有了。實際上,即便服務(wù)器的磁盤發(fā)生故障,用任何一個克隆出來的客戶端都可以重建服務(wù)器上的倉庫,回到當(dāng)初克隆時的狀態(tài)(雖然可能會丟失某些服務(wù)器端的掛鉤設(shè)置,但所有版本的數(shù)據(jù)仍舊還在,有關(guān)細節(jié)請參考第四章)??寺}庫的命令格式為gitclone[url]。比如,要克隆Ruby語言的Git代碼倉庫Grit,可以用下面的命令:$gitclonegit:///schacon/grit.git這會在當(dāng)前目錄下創(chuàng)建一個名為“grit”的目錄,其中包含一個.git的目錄,用于保存下載下來的所有版本記錄,然后從中取出最新版本的文件拷貝。如果進入這個新建的grit目錄,你會看到項目中的所有文件已經(jīng)在里邊了,準備好后續(xù)的開發(fā)和使用。如果希望在克隆的時候,自己定義要新建的項目目錄名稱,可以在上面的命令末尾指定新的名字:$gitclonegit:///schacon/grit.gitmygrit唯一的差別就是,現(xiàn)在新建的目錄成了mygrit,其他的都和上邊的一樣。Git支持許多數(shù)據(jù)傳輸協(xié)議。之前的例子使用的是git://協(xié)議,不過你也可以用http(s)://或者user@server:/path.git表示的SSH傳輸協(xié)議。我們會在第四章詳細介紹所有這些協(xié)議在服務(wù)器端該如何配置使用,以及各種方式之間的利弊。2.2
記錄每次更新到倉庫現(xiàn)在我們手上已經(jīng)有了一個真實項目的Git倉庫,并從這個倉庫中取出了所有文件的工作拷貝。接下來,對這些文件作些修改,在完成了一個階段的目標之后,提交本次更新到倉庫。請記住,工作目錄下面的所有文件都不外乎這兩種狀態(tài):已跟蹤或未跟蹤。已跟蹤的文件是指本來就被納入版本控制管理的文件,在上次快照中有它們的記錄,工作一段時間后,它們的狀態(tài)可能是未更新,已修改或者已放入暫存區(qū)。而所有其他文件都屬于未跟蹤文件。它們既沒有上次更新時的快照,也不在當(dāng)前的暫存區(qū)域。初次克隆某個倉庫時,工作目錄中的所有文件都屬于已跟蹤文件,且狀態(tài)為未修改。在編輯過某些文件之后,Git將這些文件標為已修改。我們逐步把這些修改過的文件放到暫存區(qū)域,直到最后一次性提交所有這些暫存起來的文件,如此重復(fù)。所以使用Git時的文件狀態(tài)變化周期如圖2-1所示。圖2-1.文件的狀態(tài)變化周期檢查當(dāng)前文件狀態(tài)要確定哪些文件當(dāng)前處于什么狀態(tài),可以用gitstatus命令。如果在克隆倉庫之后立即執(zhí)行此命令,會看到類似這樣的輸出:$gitstatus#Onbranchmasternothingtocommit(workingdirectoryclean)這說明你現(xiàn)在的工作目錄相當(dāng)干凈。換句話說,當(dāng)前沒有任何跟蹤著的文件,也沒有任何文件在上次提交后更改過。此外,上面的信息還表明,當(dāng)前目錄下沒有出現(xiàn)任何處于未跟蹤的新文件,否則Git會在這里列出來。最后,該命令還顯示了當(dāng)前所在的分支是master,這是默認的分支名稱,實際是可以修改的,現(xiàn)在先不用考慮。下一章我們就會詳細討論分支和引用?,F(xiàn)在讓我們用vim編輯一個新文件README,保存退出后運行g(shù)itstatus會看到該文件出現(xiàn)在未跟蹤文件列表中:$vimREADME$gitstatus#Onbranchmaster#Untrackedfiles:#(use"gitadd..."toincludeinwhatwillbecommitted)##READMEnothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)就是在“Untrackedfiles”這行下面。Git不會自動將之納入跟蹤范圍,除非你明明白白地告訴它“我需要跟蹤該文件”,因而不用擔(dān)心把臨時文件什么的也歸入版本管理。不過現(xiàn)在的例子中,我們確實想要跟蹤管理README這個文件。跟蹤新文件使用命令gitadd開始跟蹤一個新文件。所以,要跟蹤README文件,運行:$gitaddREADME此時再運行g(shù)itstatus命令,會看到README文件已被跟蹤,并處于暫存狀態(tài):$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##newfile:README#只要在“Changestobecommitted”這行下面的,就說明是已暫存狀態(tài)。如果此時提交,那么該文件此時此刻的版本將被留存在歷史記錄中。你可能會想起之前我們使用gitinit后就運行了gitadd命令,開始跟蹤當(dāng)前目錄下的文件。在gitadd后面可以指明要跟蹤的文件或目錄路徑。如果是目錄的話,就說明要遞歸跟蹤該目錄下的所有文件。(譯注:其實gitadd的潛臺詞就是把目標文件快照放入暫存區(qū)域,也就是addfileintostagedarea,同時未曾跟蹤過的文件標記為需要跟蹤。這樣就好理解后續(xù)add操作的實際意義了。)暫存已修改文件現(xiàn)在我們修改下之前已跟蹤過的文件benchmarks.rb,然后再次運行status命令,會看到這樣的狀態(tài)報告:$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tunstage)##newfile:README##Chnebunotupdated:(us"gitadd..."toupdatewhatwillbecommitted)##modified:benchmarks.rb#文件benchmarks.rb出現(xiàn)在“Changedbutnotupdated”這行下面,說明已跟蹤文件的內(nèi)容發(fā)生了變化,但還沒有放到暫存區(qū)。要暫存這次更新,需要運行g(shù)itadd命令(這是個多功能命令,根據(jù)目標文件的狀態(tài)不同,此命令的效果也不同:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區(qū),還能用于合并時把有沖突的文件標記為已解決狀態(tài)等)。現(xiàn)在讓我們運行g(shù)itadd將benchmarks.rb放到暫存區(qū),然后再看看gitstatus的輸出:$gitaddbenchmarks.rb$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##newfile:README#modified:benchmarks.rb#現(xiàn)在兩個文件都已暫存,下次提交時就會一并記錄到倉庫。假設(shè)此時,你想要在benchmarks.rb里再加條注釋,重新編輯存盤后,準備好提交。不過且慢,再運行g(shù)itstatus看看:$vimbenchmarks.rb$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##newfile:README#modified:benchmarks.rb##Changedbutnotupdated:#(use"gitadd..."toupdatewhatwillbecommitted)##modified:benchmarks.rb#怎么回事?benchmarks.rb文件出現(xiàn)了兩次!一次算未暫存,一次算已暫存,這怎么可能呢?好吧,實際上Git只不過暫存了你運行g(shù)itadd命令時的版本,如果現(xiàn)在提交,那么提交的是添加注釋前的版本,而非當(dāng)前工作目錄中的版本。所以,運行了gitadd之后又作了修訂的文件,需要重新運行g(shù)itadd把最新版本重新暫存起來:$gitaddbenchmarks.rb$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##newfile:README#modified:benchmarks.rb#忽略某些文件一般我們總會有些文件無需納入Git的管理,也不希望它們總出現(xiàn)在未跟蹤文件列表。通常都是些自動生成的文件,比如日志文件,或者編譯過程中創(chuàng)建的臨時文件等。我們可以創(chuàng)建一個名為.gitignore的文件,列出要忽略的文件模式。來看一個實際的例子:$cat.gitignore*.[oa]*~第一行告訴Git忽略所有以.o或.a結(jié)尾的文件。一般這類對象文件和存檔文件都是編譯過程中出現(xiàn)的,我們用不著跟蹤它們的版本。第二行告訴Git忽略所有以波浪符(~)結(jié)尾的文件,許多文本編輯軟件(比如Emacs)都用這樣的文件名保存副本。此外,你可能還需要忽略log,tmp或者pid目錄,以及自動生成的文檔等等。要養(yǎng)成一開始就設(shè)置好.gitignore文件的習(xí)慣,以免將來誤提交這類無用的文件。文件.gitignore的格式規(guī)范如下:所有空行或者以注釋符號#開頭的行都會被Git忽略??梢允褂脴藴实膅lob模式匹配。*匹配模式最后跟反斜杠(/)說明要忽略的是目錄。*要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(!)取反。所謂的glob模式是指shell所使用的簡化了的正則表達式。星號(*)匹配零個或多個任意字符;[abc]匹配任何一個列在方括號中的字符(這個例子要么匹配一個a,要么匹配一個b,要么匹配一個c);問號(?)只匹配一個任意字符;如果在方括號中使用短劃線分隔兩個字符,表示所有在這兩個字符范圍內(nèi)的都可以匹配(比如[0-9]表示匹配所有0到9的數(shù)字)。我們再看一個.gitignore文件的例子:#此為注釋–將被Git忽略*.a#忽略所有.a結(jié)尾的文件!lib.a#但lib.a除外/TODO#僅僅忽略項目根目錄下的TODO文件,不包括subdir/TODObuild/#忽略build/目錄下的所有文件doc/*.txt#會忽略doc/notes.txt但不包括doc/server/arch.txt查看已暫存和未暫存的更新實際上gitstatus的顯示比較簡單,僅僅是列出了修改過的文件,如果要查看具體修改了什么地方,可以用gitdiff命令。稍后我們會詳細介紹gitdiff,不過現(xiàn)在,它已經(jīng)能回答我們的兩個問題了:當(dāng)前做的哪些更新還沒有暫存?有哪些更新已經(jīng)暫存起來準備好了下次提交?gitdiff會使用文件補丁的格式顯示具體添加和刪除的行。假如再次修改README文件后暫存,然后編輯benchmarks.rb文件后先別暫存,運行status命令,會看到:$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##newfile:README##Changedbutnotupdated:#(use"gitadd..."toupdatewhatwillbecommitted)##modified:benchmarks.rb#要查看尚未暫存的文件更新了哪些部分,不加參數(shù)直接輸入gitdiff:$gitdiffdiff--gita/benchmarks.rbb/benchmarks.rbindex3cb747f..da65585100644---a/benchmarks.rb+++b/benchmarks.rb@@-36,6+36,10@@defmain@commit.parents[0].parents[0].parents[0]end+run_code(x,'commits1')do+mits.size+end+run_code(x,'commits2')dolog=mits('master',15)log.size此命令比較的是工作目錄中當(dāng)前文件和暫存區(qū)域快照之間的差異,也就是修改之后還沒有暫存起來的變化內(nèi)容。若要看已經(jīng)暫存起來的文件和上次提交時的快照之間的差異,可以用gitdiff--cached命令。(Git1.6.1及更高版本還允許使用gitdiff--staged,效果是相同的,但更好記些。)來看看實際的效果:$gitdiff--cacheddiff--gita/READMEb/READMEnewfilemode100644index0000000..03902a1---/dev/null+++b/README2@@-0,0+1,5@@+grit+byTomPreston-Werner,ChrisWanstrath+/mojombo/grit++GritisaRubylibraryforextractinginformationfromaGitrepository請注意,單單gitdiff不過是顯示還沒有暫存起來的改動,而不是這次工作和上次提交之間的差異。所以有時候你一下子暫存了所有更新過的文件后,運行g(shù)itdiff后卻什么也沒有,就是這個原因。像之前說的,暫存benchmarks.rb后再編輯,運行g(shù)itstatus會看到暫存前后的兩個版本:$gitaddbenchmarks.rb$echo'#testline'>>benchmarks.rb$gitstatus#Onbranchmaster##Changestobecommitted:##modified:benchmarks.rb##Changedbutnotupdated:##modified:benchmarks.rb#現(xiàn)在運行g(shù)itdiff看暫存前后的變化:$gitdiffdiff--gita/benchmarks.rbb/benchmarks.rbindexe445e28..86b2f7c100644---a/benchmarks.rb+++b/benchmarks.rb@@-127,3+127,4@@endmain()##ppGrit::GitRuby.cache_client.stats+#testline然后用gitdiff--cached查看已經(jīng)暫存起來的變化:$gitdiff--cacheddiff--gita/benchmarks.rbb/benchmarks.rbindex3cb747f..e445e28100644---a/benchmarks.rb+++b/benchmarks.rb@@-36,6+36,10@@defmain@commit.parents[0].parents[0].parents[0]end+run_code(x,'commits1')do+mits.size+end+run_code(x,'commits2')dolog=mits('master',15)log.size提交更新現(xiàn)在的暫存區(qū)域已經(jīng)準備妥當(dāng)可以提交了。在此之前,請一定要確認還有什么修改過的或新建的文件還沒有g(shù)itadd過,否則提交的時候不會記錄這些還沒暫存起來的變化。所以,每次準備提交前,先用gitstatus看下,是不是都已暫存起來了,然后再運行提交命令gitcommit:$gitcommit這種方式會啟動文本編輯器以便輸入本次提交的說明。(默認會啟用shell的環(huán)境變量$EDITOR所指定的軟件,一般都是vim或emacs。當(dāng)然也可以按照第一章介紹的方式,使用gitconfig--globalcore.editor命令設(shè)定你喜歡的編輯軟件。)編輯器會顯示類似下面的文本信息(本例選用Vim的屏顯方式展示):#Pleaseenterthecommitmessageforyourchanges.Linesstarting#with'#'willbeignored,andanemptymessageabortsthecommit.#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##newfile:README#modified:benchmarks.rb~~~".git/COMMIT_EDITMSG"10L,283C可以看到,默認的提交消息包含最后一次運行g(shù)itstatus的輸出,放在注釋行里,另外開頭還有一空行,供你輸入提交說明。你完全可以去掉這些注釋行,不過留著也沒關(guān)系,多少能幫你回想起這次更新的內(nèi)容有哪些。(如果覺得這還不夠,可以用-v選項將修改差異的每一行都包含到注釋中來。)退出編輯器時,Git會丟掉注釋行,將說明內(nèi)容和本次更新提交到倉庫。另外也可以用-m參數(shù)后跟提交說明的方式,在一行命令中提交更新:$gitcommit-m"Story182:Fixbenchmarksforspeed"[master]:created463dc4f:"Fixbenchmarksforspeed"2fileschanged,3insertions(+),0deletions(-)createmode100644README好,現(xiàn)在你已經(jīng)創(chuàng)建了第一個提交!可以看到,提交后它會告訴你,當(dāng)前是在哪個分支(master)提交的,本次提交的完整SHA-1校驗和是什么(463dc4f),以及在本次提交中,有多少文件修訂過,多少行添改和刪改過。記住,提交時記錄的是放在暫存區(qū)域的快照,任何還未暫存的仍然保持已修改狀態(tài),可以在下次提交時納入版本管理。每一次運行提交操作,都是對你項目作一次快照,以后可以回到這個狀態(tài),或者進行比較。跳過使用暫存區(qū)域盡管使用暫存區(qū)域的方式可以精心準備要提交的細節(jié),但有時候這么做略顯繁瑣。Git提供了一個跳過使用暫存區(qū)域的方式,只要在提交的時候,給gitcommit加上-a選項,Git就會自動把所有已經(jīng)跟蹤過的文件暫存起來一并提交,從而跳過gitadd步驟:$gitstatus#Onbranchmaster##Changedbutnotupdated:##modified:benchmarks.rb#$gitcommit-a-m'addednewbenchmarks'[master83e38c7]addednewbenchmarks1fileschanged,5insertions(+),0deletions(-)看到了嗎?提交之前不再需要gitadd文件benchmarks.rb了。移除文件要從Git中移除某個文件,就必須要從已跟蹤文件清單中移除(確切地說,是從暫存區(qū)域移除),然后提交??梢杂胓itrm命令完成此項工作,并連帶從工作目錄中刪除指定的文件,這樣以后就不會出現(xiàn)在未跟蹤文件清單中了。如果只是簡單地從工作目錄中手工刪除文件,運行g(shù)itstatus時就會在“Changedbutnotupdated”部分(也就是_未暫存_清單)看到:$rmgrit.gemspec$gitstatus#Onbranchmaster##Changedbutnotupdated:#(use"gitadd/rm..."toupdatewhatwillbecommitted)##deleted:grit.gemspec#然后再運行g(shù)itrm記錄此次移除文件的操作:$gitrmgrit.gemspecrm'grit.gemspec'$gitstatus#Onbranchmaster##Changestobecommitted:#(use"gitresetHEAD..."tounstage)##deleted:grit.gemspec#最后提交的時候,該文件就不再納入版本管理了。如果刪除之前修改過并且已經(jīng)放到暫存區(qū)域的話,則必須要用強制刪除選項-f(譯注:即force的首字母),以防誤刪除文件后丟失修改的內(nèi)容。另外一種情況是,我們想把文件從Git倉庫中刪除(亦即從暫存區(qū)域移除),但仍然希望保留在當(dāng)前工作目錄中。換句話說,僅是從跟蹤清單中刪除。比如一些大型日志文件或者一堆.a編譯文件,不小心納入倉庫后,要移除跟蹤但不刪除文件,以便稍后在.gitignore文件中補上,用--cached選項即可:$gitrm--cachedreadme.txt后面可以列出文件或者目錄的名字,也可以使用glob模式。比方說:$gitrmlog/\*.log注意到星號*之前的反斜杠\,因為Git有它自己的文件模式擴展匹配方式,所以我們不用shell來幫忙展開(譯注:實際上不加反斜杠也可以運行,只不過按照shell擴展的話,僅僅刪除指定目錄下的文件而不會遞歸匹配。上面的例子本來就指定了目錄,所以效果等同,但下面的例子就會用遞歸方式匹配,所以必須加反斜杠。)。此命令刪除所有l(wèi)og/目錄下擴展名為.log的文件。類似的比如:$gitrm\*~會遞歸刪除當(dāng)前目錄及其子目錄中所有~結(jié)尾的文件。移動文件不像其他的VCS系統(tǒng),Git并不跟蹤文件移動操作。如果在Git中重命名了某個文件,倉庫中存儲的元數(shù)據(jù)并不會體現(xiàn)出這是一次改名操作。不過Git非常聰明,它會推斷出究竟發(fā)生了什么,至于具體是如何做到的,我們稍后再談。既然如此,當(dāng)你看到Git的mv命令時一定會困惑不已。要在Git中對文件改名,可以這么做:$gitmvfile_fromfile_to它會恰如預(yù)期般正常工作。實際上,即便此時查看狀態(tài)信息,也會明白無誤地看到關(guān)于重命名操作的說明:$gitmvREADME.txtREADME$gitstatus#Onbranchmaster#Yourbranchisaheadof'origin/master'by1commit.##Changestobecommitted:#(use"gitresetHEAD..."tounstage)##renamed:README.txt->README#其實,運行g(shù)itmv就相當(dāng)于運行了下面三條命令:$mvREADME.txtREADME$gitrmREADME.txt$gitaddREADME如此分開操作,Git也會意識到這是一次改名,所以不管何種方式都一樣。當(dāng)然,直接用gitmv輕便得多,不過有時候用其他工具批處理改名的話,要記得在提交前刪除老的文件名,再添加新的文件名。2.3
查看提交歷史在提交了若干更新之后,又或者克隆了某個項目,想回顧下提交歷史,可以使用gitlog命令查看。接下來的例子會用我專門用于演示的simplegit項目,運行下面的命令獲取該項目源代碼:gitclonegit:///schacon/simplegit-progit.git然后在此項目中運行g(shù)itlog,應(yīng)該會看到下面的輸出:$gitlogcommitca82a6dff817ec66f44342007202690a93763949Author:ScottChaconDate:MonMar1721:52:112008-0700changedtheversionnumbercommit085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7Author:ScottChaconDate:SatMar1516:40:332008-0700removedunnecessarytestcodecommita11bef06a3f659402fe7563abf99ad00de2209e6Author:ScottChaconDate:SatMar1510:31:282008-0700firstcommit默認不用任何參數(shù)的話,gitlog會按提交時間列出所有的更新,最近的更新排在最上面??吹搅藛?,每次更新都有一個SHA-1校驗和、作者的名字和電子郵件地址、提交時間,最后縮進一個段落顯示提交說明。gitlog有許多選項可以幫助你搜尋感興趣的提交,接下來我們介紹些最常用的。我們常用-p選項展開顯示每次提交的內(nèi)容差異,用-2則僅顯示最近的兩次更新:$gitlog-p-2commitca82a6dff817ec66f44342007202690a93763949Author:ScottChaconDate:MonMar1721:52:112008-0700changedtheversionnumberdiff--gita/Rakefileb/Rakefileindexa874b73..8f94139100644---a/Rakefile+++b/Rakefile@@-5,7+5,7@@require'rake/gempackagetask'spec=Gem::Specification.newdo|s|-s.version="0.1.0"+s.version="0.1.1"s.author="ScottChacon"commit085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7Author:ScottChaconDate:SatMar1516:40:332008-0700removedunnecessarytestcodediff--gita/lib/simplegit.rbb/lib/simplegit.rbindexa0a60ae..47c6340100644---a/lib/simplegit.rb+++b/lib/simplegit.rb@@-18,8+18,3@@classSimpleGitendend--if$0==__FILE__-git=SimpleGit.new-putsgit.show-end\Nonewlineatendoffile在做代碼審查,或者要快速瀏覽其他協(xié)作者提交的更新都作了哪些改動時,就可以用這個選項。此外,還有許多摘要選項可以用,比如--stat,僅顯示簡要的增改行數(shù)統(tǒng)計:$gitlog--statcommitca82a6dff817ec66f44342007202690a93763949Author:ScottChaconDate:MonMar1721:52:112008-0700changedtheversionnumberRakefile|2+-1fileschanged,1insertions(+),1deletions(-)commit085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7Author:ScottChaconDate:SatMar1516:40:332008-0700removedunnecessarytestcodelib/simplegit.rb|5-----1fileschanged,0insertions(+),5deletions(-)commita11bef06a3f659402fe7563abf99ad00de2209e6Author:ScottChaconDate:SatMar1510:31:282008-0700firstcommitREADME|6++++++Rakefile|23+++++++++++++++++++++++lib/simplegit.rb|25+++++++++++++++++++++++++3fileschanged,54insertions(+),0deletions(-)每個提交都列出了修改過的文件,以及其中添加和移除的行數(shù),并在最后列出所有增減行數(shù)小計。還有個常用的--pretty選項,可以指定使用完全不同于默認格式的方式展示提交歷史。比如用oneline將每個提交放在一行顯示,這在提交數(shù)很大時非常有用。另外還有short,full和fuller可以用,展示的信息或多或少有些不同,請自己動手實踐一下看看效果如何。$gitlog--pretty=onelineca82a6dff817ec66f44342007202690a93763949changedtheversionnumber085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7removedunnecessarytestcodea11bef06a3f659402fe7563abf99ad00de2209e6firstcommit但最有意思的是format,可以定制要顯示的記錄格式,這樣的輸出便于后期編程提取分析,像這樣:$gitlog--pretty=format:"%h-%an,%ar:%s"ca82a6d-ScottChacon,11monthsago:changedtheversionnumber085bb3b-ScottChacon,11monthsago:removedunnecessarytestcodea11bef0-ScottChacon,11monthsago:firstcommit表2-1列出了常用的格式占位符寫法及其代表的意義。選項說明%H提交對象(commit)的完整哈希字串%h提交對象的簡短哈希字串%T樹對象(tree)的完整哈希字串%t樹對象的簡短哈希字串%P父對象(parent)的完整哈希字串%p父對象的簡短哈希字串%an作者(author)的名字%ae作者的電子郵件地址%ad作者修訂日期(可以用-date=選項定制格式)%ar作者修訂日期,按多久以前的方式顯示%cn提交者(committer)的名字%ce提交者的電子郵件地址%cd提交日期%cr提交日期,按多久以前的方式顯示%s提交說明你一定奇怪_作者(author)_和_提交者(committer)_之間究竟有何差別,其實作者指的是實際作出修改的人,提交者指的是最后將此工作成果提交到倉庫的人。所以,當(dāng)你為某個項目發(fā)布補丁,然后某個核心成員將你的補丁并入項目時,你就是作者,而那個核心成員就是提交者。我們會在第五章再詳細介紹兩者之間的細微差別。用oneline或format時結(jié)合--graph選項,可以看到開頭多出一些ASCII字符串表示的簡單圖形,形象地展示了每個提交所在的分支及其分化衍合情況。在我們之前提到的Grit項目倉庫中可以看到:$gitlog--pretty=format:"%h%s"--graph*2d3acf9ignoreerrorsfromSIGCHLDontrap*5e3ee11Mergebranch'master'ofgit:///dustin/grit|\|*420eac9Addedamethodforgettingthecurrentbranch.*|30e367ctimeoutcodeandtests*|5a09431addtimeoutprotectiontogrit*|e1193f8supportforheadswithslashesinthem|/*d6016bcrequiretimeforxmlschema*11d191eMergebranch'defunkt'intolocal以上只是簡單介紹了一些gitlog命令支持的選項。表2-2還列出了一些其他常用的選項及其釋義。選項說明-p按補丁格式顯示每個更新之間的差異。--stat顯示每次更新的文件修改統(tǒng)計信息。--shortstat只顯示--stat中最后的行數(shù)修改添加移除統(tǒng)計。--name-only僅在提交信息后顯示已修改的文件清單。--name-status顯示新增、修改、刪除的文件清單。--abbrev-commit僅顯示SHA-1的前幾個字符,而非所有的40個字符。--relative-date使用較短的相對時間顯示(比如,“2weeksago”)。--graph顯示ASCII圖形表示的分支合并歷史。--pretty使用其他格式顯示歷史提交信息。可用的選項包括oneline,short,full,fuller和format(后跟指定格式)。限制輸出長度除了定制輸出格式的選項之外,gitlog還有許多非常實用的限制輸出長度的選項,也就是只輸出部分提交信息。之前我們已經(jīng)看到過-2了,它只顯示最近的兩條提交,實際上,這是-選項的寫法,其中的n可以是任何自然數(shù),表示僅顯示最近的若干條提交。不過實踐中我們是不太用這個選項的,Git在輸出所有提交時會自動調(diào)用分頁程序(less),要看更早的更新只需翻到下頁即可。另外還有按照時間作限制的選項,比如--since和--until。下面的命令列出所有最近兩周內(nèi)的提交:$gitlog--since=2.weeks你可以給出各種時間格式,比如說具體的某一天(“2008-01-15”),或者是多久以前(“2years1day3minutesago”)。還可以給出若干搜索條件,列出符合的提交。用--author選項顯示指定作者的提交,用--grep選項搜索提交說明中的關(guān)鍵字。(請注意,如果要得到同時滿足這兩個選項搜索條件的提交,就必須用--all-match選項。)如果只關(guān)心某些文件或者目錄的歷史提交,可以在gitlog選項的最后指定它們的路徑。因為是放在最后位置上的選項,所以用兩個短劃線(--)隔開之前的選項和后面限定的路徑名。表2-3還列出了其他常用的類似選項。選項說明-(n)僅顯示最近的n條提交--since,--after僅顯示指定時間之后的提交。--until,--before僅顯示指定時間之前的提交。--author僅顯示指定作者相關(guān)的提交。--committer僅顯示指定提交者相關(guān)的提交。來看一個實際的例子,如果要查看Git倉庫中,2008年10月期間,JunioHamano提交的但未合并的測試腳本(位于項目的t/目錄下的文件),可以用下面的查詢命令:$gitlog--pretty="%h-%s"--author=gitster--since="2008-10-01"\--before="2008-11-01"--no-merges--t/5610e3b-Fixtestcasefailurewhenextendedattributeacd3b9e-Enhancehold_lock_file_for_{update,append}()f563754-demonstratebreakageofdetachedcheckoutwid1a43f2-reset--hard/read-tree--reset-u:removeun51a94af-Fix"checkout--track-bnewbranch"ondetacb0ad11e-pull:allow"gitpullorigin$something:$curGit項目有20,000多條提交,但我們給出搜索選項后,僅列出了其中滿足條件的6條。使用圖形化工具查閱提交歷史有時候圖形化工具更容易展示歷史提交的變化,隨Git一同發(fā)布的gitk就是這樣一種工具。它是用Tcl/Tk寫成的,基本上相當(dāng)于gitlog命令的可視化版本,凡是gitlog可以用的選項也都能用在gitk上。在項目工作目錄中輸入gitk命令后,就會啟動圖2-2所示的界面。
圖2-2.gitk的圖形界面上半個窗口顯示的是歷次提交的分支祖先圖譜,下半個窗口顯示當(dāng)前點選的提交對應(yīng)的具體差異。2.4
撤消操作任何時候,你都有可能需要撤消剛才所做的某些操作。接下來,我們會介紹一些基本的撤消操作相關(guān)的命令。請注意,有些操作并不總是可以撤消的,所以請務(wù)必謹慎小心,一旦失誤,就有可能丟失部分工作成果。修改最后一次提交有時候我們提交完了才發(fā)現(xiàn)漏掉了幾個文件沒有加,或者提交信息寫錯了。想要撤消剛才的提交操作,可以使用--amend選項重新提交:$gitcommit--amend此命令將使用當(dāng)前的暫存區(qū)域快照提交。如果剛才提交完沒有作任何改動,直接運行此命令的話,相當(dāng)于有機會重新編輯提交說明,但將要提交的文件快照和之前的一樣。啟動文本編輯器后,會看到上次提交時的說明,編輯它確認沒問題后保存退出,就會使用新的提交說明覆蓋剛才失誤的提交。如果剛才提交時忘了暫存某些修改,可以先補上暫存操作,然后再運行--amend提交:$gitcommit-m'initialcommit'$gitaddforgotten_file$gitcommit--amend上面的三條命令最終只是產(chǎn)生一個提交,第二個提交命令修正了第一個的提交內(nèi)容。取消已經(jīng)暫存的文件接下來的兩個小節(jié)將演示如何取消暫存區(qū)域中的文件,以及如何取消工作目錄中已修改的文件。不用擔(dān)心,查看文件狀態(tài)的時候就提示了該如何撤消,所以不需要死記硬背。來看下面的例子,有兩個修改過的文件,我們想要分開提交,但不小心用gitadd.全加到了暫存區(qū)域。該如何撤消暫存其中的一個文件呢?其實,gitstatus的命令輸出已經(jīng)告訴了我們該怎么做:$gitadd.$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##modified:README.txt#modified:benchmarks.rb#就在“Changestobecommitted”下面,括號中有提示,可以使用gitresetHEAD...的方式取消暫存。好吧,我們來試試取消暫存benchmarks.rb文件:$gitresetHEADbenchmarks.rbbenchmarks.rb:locallymodified$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##modified:README.txt##Changedbutnotupdated:#(use"gitadd..."toupdatewhatwillbecommitted)#(use"gitcheckout--..."todiscardchangesinworkingdirectory)##modified:benchmarks.rb#這條命令看起來有些古怪,先別管,能用就行?,F(xiàn)在benchmarks.rb文件又回到了之前已修改未暫存的狀態(tài)。取消對文件的修改如果覺得剛才對benchmarks.rb的修改完全沒有必要,該如何取消修改,回到之前的狀態(tài)(也就是修改之前的版本)呢?gitstatus同樣提示了具體的撤消方法,接著上面的例子,現(xiàn)在未暫存區(qū)域看起來像這樣:#Changedbutnotupdated:#(use"gitadd..."toupdatewhatwillbecommitted)#(use"gitcheckout--..."todiscardchangesinworkingdirectory)##modified:benchmarks.rb#在第二個括號中,我們看到了拋棄文件修改的命令(至少在Git1.6.1以及更高版本中會這樣提示,如果你還在用老版本,我們強烈建議你升級,以獲取最佳的用戶體驗),讓我們試試看:$gitcheckout--benchmarks.rb$gitstatus#Onbranchmaster#Changestobecommitted:#(use"gitresetHEAD..."tounstage)##modified:README.txt#可以看到,該文件已經(jīng)恢復(fù)到修改前的版本。你可能已經(jīng)意識到了,這條命令有些危險,所有對文件的修改都沒有了,因為我們剛剛把之前版本的文件復(fù)制過來重寫了此文件。所以在用這條命令前,請務(wù)必確定真的不再需要保留剛才的修改。如果只是想回退版本,同時保留剛才的修改以便將來繼續(xù)工作,可以用下章介紹的stashing和分支來處理,應(yīng)該會更好些。記住,任何已經(jīng)提交到Git的都可以被恢復(fù)。即便在已經(jīng)刪除的分支中的提交,或者用--amend重新改寫的提交,都可以被恢復(fù)(關(guān)于數(shù)據(jù)恢復(fù)的內(nèi)容見第九章)。所以,你可能失去的數(shù)據(jù),僅限于沒有提交過的,對Git來說它們就像從未存在過一樣。2.5
遠程倉庫的使用要參與任何一個Git項目的協(xié)作,必須要了解該如何管理遠程倉庫。遠程倉庫是指托管在網(wǎng)絡(luò)上的項目倉庫,可能會有好多個,其中有些你只能讀,另外有些可以寫。同他人協(xié)作開發(fā)某個項目時,需要管理這些遠程倉庫,以便推送或拉取數(shù)據(jù),分享各自的工作進展。管理遠程倉庫的工作,包括添加遠程庫,移除廢棄的遠程庫,管理各式遠程庫分支,定義是否跟蹤這些分支,等等。本節(jié)我們將詳細討論遠程庫的管理和使用。查看當(dāng)前的遠程庫要查看當(dāng)前配置有哪些遠程倉庫,可以用gitremote命令,它會列出每個遠程庫的簡短名字。在克隆完某個項目后,至少可以看到一個名為origin的遠程庫,Git默認使用這個名字來標識你所克隆的原始倉庫:$gitclonegit:///schacon/ticgit.gitInitializedemptyGitrepositoryin/private/tmp/ticgit/.git/remote:Countingobjects:595,done.remote:Compressingobjects:100%(269/269),done.remote:Total595(delta255),reused589(delta253)Receivingobjects:100%(595/595),73.31KiB|1KiB/s,done.Resolvingdeltas:100%(255/255),done.$cdticgit$gitremoteorigin也可以加上-v選項(譯注:此為--verbose的簡寫,取首字母),顯示對應(yīng)的克隆地址:$gitremote-vorigingit:///schacon/ticgit.git如果有多個遠程倉庫,此命令將全部列出。比如在我的Grit項目中,可以看到:$cdgrit$gitremote-vbakkdoorgit:///bakkdoor/grit.gitcho45git:///cho45/grit.gitdefunktgit:///defunkt/grit.gitkokegit:///koke/grit.gitorigingit@:mojombo/grit.git這樣一來,我就可以非常輕松地從這些用戶的倉庫中,拉取他們的提交到本地。請注意,上面列出的地址只有origin用的是SSHURL鏈接,所以也只有這個倉庫我能推送數(shù)據(jù)上去(我們會在第四章解釋原因)。添加遠程倉庫要添加一個新的遠程倉庫,可以指定一個簡單的名字,以便將來引用,運行g(shù)itremoteadd[shortname][url]:$gitremoteorigin$gitremoteaddpbgit:///paulboone/ticgit.git$gitremote-vorigingit:///schacon/ticgit.gitpbgit:///paulboone/ticgit.git現(xiàn)在可以用字串pb指代對應(yīng)的倉庫地址了。比如說,要抓取所有Paul有的,但本地倉庫沒有的信息,可以運行g(shù)itfetchpb:$gitfetchpbremote:Countingobjects:58,done.remote:Compressingobjects:100%(41/41),done.remote:Total44(delta24),reused1(delta0)Unpackingobjects:100%(44/44),done.Fromgit:///paulboone/ticgit*[newbranch]master->pb/master*[newbranch]ticgit->pb/ticgit現(xiàn)在,Paul的主干分支(master)已經(jīng)完全可以在本地訪問了,對應(yīng)的名字是pb/master,你可以將它合并到自己的某個分支,或者切換到這個分支,看看有些什么有趣的更新。從遠程倉庫抓取數(shù)據(jù)正如之前所看到的,可以用下面的命令從遠程倉庫抓取數(shù)據(jù)到本地:$gitfetch[remote-name]此命令會到遠程倉庫中拉取所有你本地倉庫中還沒有的數(shù)據(jù)。運行完成后,你就可以在本地訪問該遠程倉庫中的所有分支,將其中某個分支合并到本地,或者只是取出某個分支,一探究竟。(我們會在第三章詳細討論關(guān)于分支的概念和操作。)如果是克隆了一個倉庫,此命令會自動將遠程倉庫歸于origin名下。所以,gitfetchorigin會抓取從你上次克隆以來別人上傳到此遠程倉庫中的所有更新(或是上次fetch以來別人提交的更新)。有一點很重要,需要記住,fetch命令只是將遠端的數(shù)據(jù)拉到本地倉庫,并不自動合并到當(dāng)前工作分支,只有當(dāng)你確實準備好了,才能手工合并。如果設(shè)置了某個分支用于跟蹤某個遠端倉庫的分支(參見下節(jié)及第三章的內(nèi)容),可以使用gitpull命令自動抓取數(shù)據(jù)下來,然后將遠端分支自動合并到本地倉庫中當(dāng)前分支。在日常工作中我們經(jīng)常這么用,既快且好。實際上,默認情況下gitclone命令本質(zhì)上就是自動創(chuàng)建了本地的master分支用于跟蹤遠程倉庫中的master分支(假設(shè)遠程倉庫確實有master分支)。所以一般我們運行g(shù)itpull,目的都是要從原始克隆的遠端倉庫中抓取數(shù)據(jù)后,合并到工作目錄中的當(dāng)前分支。推送數(shù)據(jù)到遠程倉庫項目進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的數(shù)據(jù)推送到遠程倉庫。實現(xiàn)這個任務(wù)的命令很簡單:gitpush[remote-name][branch-name]。如果要把本地的master分支推送到origin服務(wù)器上(再次說明下,克隆操作會自動使用默認的master和origin名字),可以運行下面的命令:$gitpushoriginmaster只有在所克隆的服務(wù)器上有寫權(quán)限,或者同一時刻沒有其他人在推數(shù)據(jù),這條命令才會如期完成任務(wù)。如果在你推數(shù)據(jù)前,已經(jīng)有其他人推送了若干更新,那你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,合并到自己的項目中,然后才可以再次推送。有關(guān)推送數(shù)據(jù)到遠程倉庫的詳細內(nèi)容見第三章。查看遠程倉庫信息我們可以通過命令gitremoteshow[remote-name]查看某個遠程倉庫的詳細信息,比如要看所克隆的origin倉庫,可以運行:$gitremoteshoworigin*remoteoriginURL:git:///schacon/ticgit.gitRemotebranchmergedwith'gitpull'whileonbranchmastermasterTrackedremotebranchesmasterticgit除了對應(yīng)的克隆地址外,它還給出了許多額外的信息。它友善地告訴你如果是在master分支,就可以用gitpull命令抓取數(shù)據(jù)合并到本地。另外還列出了所有處于跟蹤狀態(tài)中的遠端分支。上面的例子非常簡單,而隨著使用Git的深入,gitremoteshow給出的信息可能會像這樣:$gitremoteshoworigin*remoteoriginURL:git@:defunkt/github.gitRemotebranchmergedwith'gitpull'whileonbranchissuesissuesRemotebranchmergedwith'gitpull'whileonbranchmastermasterNewremotebranches(nextfetchwillstoreinremotes/origin)cachingStaletrackingbranches(use'gitremoteprune')libwalkerwalker2Trackedremotebranchesaclapiv2dashboard2issuesmasterpostgresLocalbranchpushedwith'gitpush'master:master它告訴我們,運行g(shù)itpush時缺省推送的分支是什么(譯注:最后兩行)。它還顯示了有哪些遠端分支還沒有同步到本地(譯注:第六行的caching分支),哪些已同步到本地的遠端分支在遠端服務(wù)器上已被刪除(譯注:Staletrackingbranches下面的兩個分支),以及運行g(shù)itpull時將自動合并哪些分支(譯注:前四行中列出的issues和master分支)。遠程倉庫的刪除和重命名在新版Git中可以用gitremoterename命令修改某個遠程倉庫在本地的簡短名稱,比如想把pb改成paul,可以這么運行:$gitremoterenamepbpaul$gitremoteoriginpaul注意,對遠程倉庫的重命名,也會使對應(yīng)的分支名稱發(fā)生變化,原來的pb/master分支現(xiàn)在成了paul/master。碰到遠端倉庫服務(wù)器遷移,或者原來的克隆鏡像不再使用,又或者某個參與者不再貢獻代碼,那么需要移除對應(yīng)的遠端倉庫,可以運行g(shù)itremoterm命令:$gitremotermpaul$gitremoteorigin2.6
打標簽同大多數(shù)VCS一樣,Git也可以對某一時間點上的版本打上標簽。人們在發(fā)布某個軟件版本(比如v1.0等等)的時候,經(jīng)常這么做。本節(jié)我們一起來學(xué)習(xí)如何列出所有可用的標簽,如何新建標簽,以及各種不同類型標簽之間的差別。列顯已有的標簽列出現(xiàn)有標簽的命令非常簡單,直接運行g(shù)ittag即可:$gittagv0.1v1.3顯示的標簽按字母順序排列,所以標簽的先后并不表示重要程度的輕重。我們可以用特定的搜索模式列出符合條件的標簽。在Git自身項目倉庫中,有著超過240個標簽,如果你只對1.4.2系列的版本感興趣,可以運行下面的命令:$gittag-l'v1.4.2.*'vvvv新建標簽Git使用的標簽有兩種類型:輕量級的(lightweight)和含附注的(annotated)。輕量級標簽就像是個不會變化的分支,實際上它就是個指向特定提交對象的引用。而含附注標簽,實際上是存儲在倉庫中的一個獨立對象,它有自身的校驗和信息,包含著標簽的名字,電子郵件地址和日期,以及標簽說明,標簽本身也允許使用GNUPrivacyGuard(GPG)來簽署或驗證。一般我們都建議使用含附注型的標簽,以便保留相關(guān)信息;當(dāng)然,如果只是臨時性加注標簽,或者不需要旁注額外信息,用輕量級標簽也沒問題。含附注的標簽創(chuàng)建一個含附注類型的標簽非常簡單,用-a(譯注:取annotated的首字母)指定標簽名字即可:$gittag-av1.4-m'myversion1.4'$gittagv0.1v1.3v1.4而-m選項則指定了對應(yīng)的標簽說明,Git會將此說明一同保存在標簽對象中。如果沒有給出該選項,Git會啟動文本編輯軟件供你輸入標簽說明。可以使用gitshow命令查看相應(yīng)標簽的版本信息,并連同顯示打標簽時的提交對象。$gitshowv1.4tagv1.4Tagger:ScottChaconDate:MonFeb914:45:112009-0800myversion1.4commi64cf874c3557a0f3547bd83b3ff6Merge:4a447f7...a6b4c97...Author:ScottChaconDate:SunFeb819:02:462009-0800Mergebranch'experiment'我們可以看到在提交對象信息上面,列出了此標簽的提交者和提交時間,以及相應(yīng)的標簽說明。簽署標簽如果你有自己的私鑰,還可以用GPG來簽署標簽,只需要把之前的-a改為-s(譯注:取signed的首字母)即可:$gittag-sv1.5-m'mysigned1.5tag'Youneedapassphrasetounlockthesecretkeyforuser:"ScottChacon"1024-bitDSAkey,IDF721C45A,created2009-02-09現(xiàn)在再運行g(shù)itshow會看到對應(yīng)的GPG簽名也附在其內(nèi):$gitshowv1.5tagv1.5Tagger:ScottChaconDate:MonFeb915:22:202009-0800mysigned1.5tag-----BEGINPGPSIGNATURE-----Version:GnuPGv1.4.8(Darwin)iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySNKi0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/=WryJ-----ENDPGPSIGNATURE-----commi64cf874c3557a0f3547bd83b3ff6Me
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度建筑工地勞務(wù)外包安全協(xié)議范本
- 二零二五年度智能穿戴設(shè)備專利技術(shù)授權(quán)合同
- 2025年度私人老板高端家政服務(wù)用工合同
- 二零二五年度裝卸搬運安全風(fēng)險評估合作協(xié)議
- 二零二五年度貸款合同簽訂流程與貸款利率調(diào)整機制
- 二零二五年度地下車庫車位租賃與停車場安全監(jiān)控合同
- 二零二五年度電商檔口租賃管理合同
- 二零二五年度XX家居建材收取管理費合作協(xié)議
- 知產(chǎn)教育在商業(yè)合作中的價值體現(xiàn)
- 科技類企業(yè)如何運用社交媒體增強競爭力
- 《礦產(chǎn)地質(zhì)勘查規(guī)范 花崗偉晶巖型高純石英原料》(征求意見稿)
- 關(guān)尹子教射課件
- 《合同能源管理介紹》課件
- 養(yǎng)殖駱駝的可行性方案
- 汽車運用與維修專業(yè)(新能源方向)調(diào)研報告
- 2024全國一體化政務(wù)大數(shù)據(jù)體系數(shù)據(jù)交換要求
- DL-T 2578-2022 沖擊式水輪發(fā)電機組啟動試驗規(guī)程
- 兆歐表的使用課稿
- 勞動教育-專題一崇尚勞動(勞動的意義)
- 企業(yè)勞動模范頒獎詞(四篇)
- 第四課探索認識的奧秘(導(dǎo)學(xué)案)- 高中政治統(tǒng)編版必修四 哲學(xué)與文化
評論
0/150
提交評論