日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

代码打补丁的利器——diff和patch

發布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 代码打补丁的利器——diff和patch 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? 一般來說,如果我們在研發過程中需要對代碼進行修改,是不需要通過打補丁的方式的,因為我們可以直接改動文件即可。但是如果針對一款要上線的產品,我們總不能在研發的電腦上編譯通過后直接發布到線上的。(轉載請指明出于breaksoftware的csdn博客)因為這樣做有很多缺陷:

  • 最后負責編譯的同事,可能忘記提交最終的代碼。這樣代碼庫中的代碼邏輯和線上運行的產品邏輯將存在差異。
  • 最后負責編譯的同事的編譯環境可能已經感染病毒,從而導致編譯的產品也攜帶病毒。這樣的產品發布到線上將污染生產環境。
  • 無法保證最后負責編譯的同事是否對產品邏輯“做過手腳”。
  • 無法保證最后負責編譯的系統版本和關聯庫版本和線上環境一致。

? ? ? ? 因為存在種種弊端,所以很多公司都會有專門的編譯系統。大家把代碼提交到代碼庫,然后觸發編譯平臺。編譯平臺會挑選一些編譯環境將代碼從代碼庫中拉取下來,然后在這些與外網隔絕的穩定環境中進行代碼編譯。這樣可以杜絕上述問題。

? ? ? ? 在一些成規模的公司,會有很多可供大家公用的代碼庫。如果我們要實現一個功能,可能會用到這些代碼庫——即依賴,其與我們工程的關系可以分為以下兩種:

  1. 把這些依賴放在我們工程代碼內部,成為我們自己的私有代碼。
  2. 依賴以獨立模塊存在,不屬于我們自己維護的工程代碼。只有在編譯前才拉取下來。

? ? ? ? ?可以看出方案1非常不易于維護,因為我們的依賴庫會不定期更新,這樣就需要定期檢查每個依賴庫是否有更新并同步更新。而方案2可以讓我們從上述繁瑣的工作中解脫出來。我們只要在編譯前把庫(可能是最新的)拉取到本地或者編譯環境下即可,而不用關心庫的維護者什么時候進行了更新。因此。一般項目我們都是選用方案2的。

? ? ? ? 上述看著一切都很美好。而然現實往往比理想要復雜很多。比如我們發現依賴庫存在bug,而維護者沒有時間去驗證bug從而無法提供一個我們認為“穩定”的版本。我們又無法登陸公司的編譯環境(實際上公司也不會讓普通員工登陸編譯環境,否則就太危險了),不可以手工修改依賴庫的代碼。這種條條規則框住的“無解”問題怎么辦?給代碼打patch此時就有了用武之地了。

? ? ? ? 給代碼打patch需要用到兩個工具——diff和patch,它們都是linux系統上工具,我們可以很放心的使用。

? ? ? ? diff工具是用于生成補丁文件的。比如依賴庫文件中文件A.cpp有bug,我們修改了bug并將文件另存為A_modify.cpp,這樣通過下面命令生成補丁文件A_patch.cpp

diff -up A.cpp A_modify.cpp > A_patch.cpp

? ? ? ??

? ? ? ? 在編譯前,調用下面指令將補丁臨時放到依賴庫的A.cpp中

patch -p0 < A_patch.cpp

? ? ? ??

? ? ? ? 這個時候A.cpp代碼就已經沒有bug了,我們執行編譯。等編譯結束后,我們可以使用下面指令,還原A.cpp到原始的內容,即去除補丁

patch -RE -p0 < A_patch.cpp

? ? ? ?

? ? ? ? ?舉個例子:src目錄下有不能修改的代碼,而我們需要修改其中若干個文件。則我們將創建一個叫做modiy_src的目錄,其中文件和src中文件相對路徑一致。這樣我們就可以修改modify_src下的代碼,然后使用cmp工具對比每個文件。如果發現modify_src中的文件和src中的文件不一致,則在patch_src目錄下生成一個相對路徑一致的補丁文件

#!/bin/shfunction left_to_right(){for element in `ls $1`doleft_dir_or_file=$1"/"$elementright_dir_or_file=$2"/"$elementpatch_dir_or_file=$3"/"$elementif [ -d $left_dir_or_file ];thenleft_to_right $left_dir_or_file $right_dir_or_file $patch_dir_or_fileelseextension=${left_dir_or_file##*.}if [ "$extension"  != "c" -a  "$extension"  != "h" ];thencontinuefiif [ ! -f "$right_dir_or_file" ];thenright_path_floder=$(dirname $right_dir_or_file)if [ ! -d "$right_path_floder" ];thenmkdir -p $right_path_floderficp $left_dir_or_file $right_dir_or_fileelsecmp -s $left_dir_or_file $right_dir_or_filedifferent=$?if [ 0 == $different ];thencontinuefipatch_path_floder=$(dirname $patch_dir_or_file)if [ ! -d "$patch_path_floder" ];thenmkdir -p $patch_path_floderfidiff -up $left_dir_or_file $right_dir_or_file > $patch_dir_or_filefifidone
}left_to_right src/ modify_src/ patch_src/

? ? ? ? 然后再寫一個腳本,對patch_src下文件進行遍歷,并且根據傳入的參數決定“打補丁”還是“去除補丁”。

#!/bin/shfunction patch_files(){if [ "$2" == "recover" ];thencover=0elif [ "$2" == "cover" ];thencover=1elseecho "sh patch_files cover/recover"exitfifor element in `ls $1`dopatch_dir_or_file=$1"/"$elementif [ -d $patch_dir_or_file ];thenpatch_files $patch_dir_or_file $2elseif [ 0 == $cover ];thenpatch -RE -p0 < $patch_dir_or_fileelsepatch -p0 < $patch_dir_or_filefifidone
}patch_files patch_src/ $1

? ? ? ? 這樣在編譯時我們這么做,以保證編譯正確的代碼,同時在編譯結束后將代碼還原

sh ./patch_files.sh cover
make
sh ./patch_files.sh recover

總結

以上是生活随笔為你收集整理的代码打补丁的利器——diff和patch的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。