Version management using CVS

zhaozj2021-02-08  391

Version management using CVS

Translation: Liao Bin # // # Using CVS Version Management # 2000-6-30 # cvs 1.10.7 # # # Per Cederqvist et al # 斌 译 # 箐箐 的 箐箐 输入 和 # CopyRigh: GPL # # // Quick content index 1. Overview ............................................. ........ 1 2. Code warehouse .............................................. ..... 7 3. Start a project using CVS ........................................ 29 4. Rabi ........................................ 33 5. Branch and merge ........................................... .... 41 6. Recarsive Behavior ....................................... 49 7. Increase, delete, rename files and directories ................................... 51 8. Review the development history ........................................... ..57 9. Place binary files ........................................... 59 more than 10 developers of work ........................................ 61 11 Dunk Version Management ..................................................... 12 keyword replacement .......................................... ..73 13 tracking third-party code ........................................ ..... 77 14 How your system interacts with CVS .................................. .... 81 15 special file ........................................ ........... 83 16 Appendix 1) CVS command orientation ............................. ..................... 85 2) CVS command Quick reference ........................ ....................................................................... ....................................................................... ................. 141 5) Compatibility between CVS all ...................... ................ 143 6) I have encountered problems ......................... ...................... 145 7) Credits ...................... ............................ 153 8)

Always deal with CVS and this manual .................................... 155 Directory .... ................................................ ..... 157 1 Introduction This chapter is written by people who have never used CVS, may have never used any version control tools before. 1.1 What is CVS? CVS is a version control system that uses it you can record the history of your original code file. For example, when the software is modified (* bugs is translated into a problem here), and you may not find these problems for a long time after doing this. With CVS, you can easily review the old code versions to find which changes cause these issues. Sometimes it will be very helpful. You may keep your code versions of your code, which may waste you a lot of code space. CVS uses a smart approach to save your multiple versions in a file. It only reserves the different contents of the version. If you are one of a group of members in a project, CVS can help you. Unless you are particularly careful, you easily cover the work of others. Some editors, such as GNUEMACS, try to determine if a file is modified simultaneously. Unfortunately, this security method will no longer be effective if a person uses other editors. CVS uses the problem of different developers to work independently. Every developer's work is within his own directory, and CVS will work after each developer's work. CVS is created by Dick Grune as a branch of a shell script, in October 1986, when it is delivered to the newsgroup company company company company. Soures.Unix. However, there is no code in this script in these scripts now. In March 1989, Brian Berlinor designed and wrote CVS code. Jett.polk has later helped Brian to complete the design and commercial version support of the CVS model. You can get CVS in different ways, including free download on the Internet. If you want to download CVS and other CVS articles to get more information, please see: http://www.cyxlic.com http://www.loria.fr/~molli/cvs-index.html. There is a call The message list of Info-CVS is about the content of CVS. Subscribe or cancel Subscribe This list is sent to INFO-CVS-REQUEST@gnu.org If you prefer the usenet newsgroup, CVS discussion group is comp.software.confg.mgmt. In the future, you will build a comm.software. Confg.mgmt.cvs Newsgroup, but maybe this will be comp.software.confg.mgmt there after too much discussion. You may want to subscribe to the Bug-CVS mailing list, which has more information in Appendix H [BUGS]. Subscribe to it, please send email to bug-cvs-reqnest@gnu.org. 1.2 CVS can't do (unrelated) 2 3 Start a project using CVS ================= ====== Because the file name is changed, it does not often happen to another directory, so the first thing you want to do when you start a new project is to consider your document organization. Changing the file name or mobile file is not impossible, but adds potential puzzle of understanding, and CVS is particularly sensitive to the directory of the name. See Section 7.4 [Mobile File]. (* Translator Note: The name and movement in UNIX are the same).

The next step is to do in the hands of the hand. 3.1 Establishing a file The first step is to create a file in the warehouse. This can be done using a variety of different ways. -------------------------------------------------- ------------------ 3.1.1 Creating a directory tree When you start using CVS, you may have several projects can be managed using CVS. In this case, the easiest way is to use: "import" command. An example is the most easily explained how to use it. Assuming that you have some files you want to put in CVS in "WDIR", and you want them to be placed in the data warehouse: "$ cvsroot / yoyodyne / rdir" You can use the following command: $ CD WDIR $ cvs inport -m "inported" yoyodyne / rdir yoyo start If you do not use the "-m" parameter to record a log information, CVS will call an editor (* Translator Note: Usually VI) and prompts to enter information. "YOYO" string is the developer title, "start" is the issuance mark. They don't have any special meaning, just because the needs of CVS are placed here. See Chapter 13 [Track Code] to get more information. You can now check if it is valid, then you can delete your original code catalog. $ cd $ mv Dir Dir.orig $ CVS Checkout YOYODYNE / DIR $ DIFF -R DIRIG YOYODYNE / DIR $ RM -R Dir.orig. In order to avoid accidental entry into edit files, delete the original code It is a good idea. Of course, keeping a backup to other places before you delete it is also wise. The "checkout" command can use the module name as the parameter (as previously all examples) or a path relative to $ cvsroot, like the above example. You should check if the permissions in the CVS directory are appropriate and should make them belong to a particular group. See 2.2.2. Section [File Permissions]. If you want some files of "import", you can use some special methods to indicate whether these files are binary files. See C.2 [Wrappers]. -------------------------------------------------- ---------------------------------- 3.1.2 Establish a file from other version control systems If you have another version Control system maintenance projects, such as RCS, you may want to put these files in CVS and retain history of these files. Here are some discussions. From RCS: If you use RCS, find RCS files ?? Usually a file called "foo.c" will have RCS files for "RCS / FOO.c, V". (However, it is possible to see the RCS documentation in other places to get relevant information). If the file directory is not in CVS, create it in CVS. These files are then copied to the CVS repository catalog (the names in the warehouse must be ", V" original file; these files are placed directly in this directory in CVS, not the "RCS" subdirectory). This is a case where a few countless direct access to the CVS warehouse in CVS, but does not use the CVS command.

Then you can put them in the new directory "Checkout". When you move the RCS file in CVS, the RCS file should be in a state that is not locked, otherwise the CVS will appear some problems when mobile operations. All of the other version control tools Many version control tools can output standard documents in the "RCS" format. If your version control tool can do this, output the RCS file directly, then follow the example above. If your version tool does not output the RCS file, you must write a script file, take a version and put it in the CVS each time. The "Sccsarcs" script mentioned below is a good example. From SCCS: Script file with a "sccsarcs" can do converting SCCS files into RCS files, this file is placed in the "Contrib" directory of the CVS original code directory. Note: You must run it on a machine where RCS and SCCS is installed simultaneously. Also, just like other scripts in the "Contrib." Directory. (Your method may be a multi-end) (* Translator Note: I didn't look at the CVS Contrib Directory :-(, I don't know what this is something). From PVCS: There is a call in "Contrb" "Pves-to-rcs" scripts can be converted to the PVCS to RCS files. You must run it on a machine with PVCs and RCS. Please see the annotations in the script to get more details. 3.1.3 From nothing There is a new directory tree to establish a new project. The easiest way is to create an empty directory tree as follows: $ mkdir TC $ mkdir tc / man $ mkdir tc / testing After this, you can "import" this (Empty) Directory to the warehouse. $ CD TC $ CVS IMPORT -M "CREATED DIRECTORY STRUCTURE" YOYODYNE / DIR YOYO Start Then, add a file (or directory) to the warehouse when adding a file. Check if $ cvsroot Whether the permissions are correct. -------------------------------------------- ---------------------------------------------- 3.2 Definition module The next step is to define a module in the "ModuYes" file. This is not strict, but the module can easily associate the relevant directory and files. The following example can fully demonstrate how to define the module. 1. Get a copy of the module file. $ CVS CHECKOUT CVSROOT / MODULES $ CD CVSROOT 2. Edit this file and write to the defined module. See Section 2.4 [Management File ". There is a brief introduction, see C.1 [Module file]. Have it Detailed description.

You can use the row definition module "TC": TC Yoyodyne / TC 3. Submit your change to the warehouse $ cvit -m "Added Tc Module." Modules 4. Release Module File $ CD $ CVS Release -d CvsRoot 4 ======= 5 Branches and merge ================== CVS allow you to independently an derived code to a separate development version - branch. These changes do not appear in the main development version and other branch versions when you change the files in a branch. After this, you can use the merging to move these changes from one branch to another (or the main development). The merge involves using the "CVS Update -j" command to merge these changes to a working directory. You can confirm this version and thus affect the copy of these changes to other branches. -------------------------------------------------- -------------------------------- 5.1 When to create a branch assume that the Tc.c release has been completed. You are continuing to develop TC.c, which is planned to issue a version of 1.1 after 2 months. Soon, your customers start complaining that the code is some problem, you check the release of 1.0 (see 4.4 [Detection]) and find this error (this will have a small correction). However, this current version is in an unstable state, and it can be stable in the next month. This will have no way to issue a newest version to correct the problem. At this time, you can create a branch based on this version tree version 1.0. You can modify the branch of this tree without affecting the trunk. When the revision is complete, you can choose whether to merge it with a trunk or continue to keep it in this branch. -------------------------------------------------- --------------------------------- 5.2 Creating a branch You can use "tag -b" to create a branch. For example, assuming that you are working in a working copy: $ cvs tag -b Rel_1_0_patches This will separate a branch based on the current copy and assign the name of "Rel_1_0_patches". Knowing the branch is created in a CVS repository, not very important in the work copy. The example is the example, creating a branch based on the current version does not automatically transfer the current work copy to the new branch. For more information, please see 5.3 [Enter a branch]. You can also create a branch without referring to any working copy. You can use the RTAG command: CVS RTAG -B -R REL-1-0 REL-1-0-Patches Tc. "-R Rel-1-0" Description This branch is based on the version file with Rel-1-0. It doesn't start branching from the latest version. This is useful for branching from the old version (for example, when amending a past stable version) When using the "TAG" flag, this "-b" flag tells RTAG to create a branch (not this version of the symbol) connection). Note that tag "Rel-1-0" may have a different version number for different files. Therefore, the result of this command is to establish a new version of the branch named "Rel-1-0-Patches" for the TC module, which is based on a version of the tree labeled "Rel-1-0".

-------------------------------------------------- -------------------------------- 5.3 Enter branches You can enter branches in two ways: re-checkout or from Existing copies enter. Re-checkout Use the checkout command and bring the "-r" identifier, followed by this branch's title (TAG) name. (See 5.2 [Create a branch]): $ cvs checkout -r rel-1-0-patches tc. Or if you already have a copy, you can use the "Update -r" command to turn to this branch. $ cvs update -r rel-1-0-patches tc. Or use another equivalent command: $ cd tc $ cvs update -r Rel-1-0-Patches This for existing copies of the backbone code or other branches It is vaild. The above command will turn it to the branch of the name. Similar to the "Update" command. "Update -R" merges any changes you have made, please note if there is conflict. One, your work copy has turned to a specific branch. It will remain in this branch unless you do other operations. This means that the change from this job CHECKIN will be added to the new version of this branch without affecting the backbone and other branch code. Want to see which branch is based on which branch is based, you can use the "status" command. Find a "sticky tag" domain in their output (see Section 4.9 ["Sticky Tag", page 38). That is your current branch.

$ cvs status -v driver.c backend.c ========================================== ============================= File: driver.c status: up-to-date version: 1.7 Sat Dec s 18:25 : 54 1992 RCS Version: 1.7 /u/cvsroot/yoyodyne/tc/driver.c ,v sticky tag: rel-1-0-patches (branch: 1.7.2) sticky date: (none) stick option: (NONE) EXISTING TAG: REL-1-0-Patches (BRANCK: 1.7.2) REL-1-0 (Revision: 1.7) ======================= ===============================================================Backend.c Status: Up-to-Date Version: 1.4 Tue Dec 1 14:39:01 RCS Version: 1.4 / U / CVSROOT / YOYODYNE / TC / Sticky Tag: Rel-1-0Patches (BRANCH: 1.4.2) Sticky Date: ( None Sticky Option: (None) EXISTING TAG: REL-1-0-Patches (Branch: 1.4.2) REL-1-0 (Revision: 1.4) Rel-0-4 (Revision: 1.4) Please do not because each The branch of the document is different ("1.7.2" and 1.4.2 ") is confused.

The branch is the same: "Rel-1-0-Patches", which files in these same devices are the same branch. In the above example, before the branch is established, "Driver.c" has more changes than "backend.c", so their version number is different. See Section 5.4 [branch and backbone version] to understand the details of how branches build the principle. -------------------------------------------------- ------------------------------------ 5.4 Branch and the backbone version usually, a document of a file is a history. A growth line (see 4.1 [Dunk version] page): --- ----- -- ----- ---- ! 1.1! ----! 1.2! ----! 1.3! ----! 1.4! ----! 1.5! --- -- ----- --- ----- However, CVS is not limited to linear development. The trunk version can be divided into different branches, each branch can be an independent self-maintenance development line. The changes in one branch can be easily transferred to the backbone. Each branch has a branch, by a "." Separated decimal odd number, the branch number is dependent on the main line version it separates. Multiple branches are allowed to separate from a specific version. All branch versions are dependent on its original separation version number. The following example will show this. ----------- 1.2.2.3.2 branch -> -! 1.2.2.3.2.1!! ----------- ! ------- ------ -------- 1.2.2 Branch -> -! 1.2.2.1! --- -! 1.2.2.2! ----! 1.2.2.2! ------- ------ -------- ! ! --- ----- ---- -- ----- ! 1.1! ----! 1.2! ---- ! 1.3! ----! 1.4! ----! 1.5! <- Carne ----- --- ---- --- - ---- !!! --------- ------- -------- 1.2.4 Branch -> - ! 1.2.4.1! ----! 1.2.4.2! ----! 1.2.4.2! ------- ------- ---- ---- How do you create a specific branch number is usually not you need to think, but talk about how it works. When CVS establishes a branch number, it first gets the first unused even number, the beginning of the number is 2, for example, when you create a branch from 6.4's backbone, the branch number is 6.4.2 All branch numbers are 0. The number is used inside CVS, (for example, 6.4.0).

(See Section 5.5 [Internal Subject No. 44) Branch 1.1.1 has special meaning, please see 13 chapters [Track Code]. -------------------------------------------------- -------------------------------- 5.5 Internal Size Number This section describes the internal branch of CVS (Magic Branches) * Translator Note: MAGIC BRANCH is translated into internal branching features. In most cases, you don't have to consider internal branch numbers, CVS will manage you for you. However, under some specific conditions, it will appear, so it will be useful to understand how it will work. In general, the branch number will consist of an odd "." Separated decimal integer. Please see 4.1 [version number]. However, it is not entirely, because of the efficiency, CVS is sometimes inserted into an additional "0" on the second position of the right end (1.2.4 becomes 1.2.0.4, 8.9.10.11. .0.12, etc.). CVS will be well carried out behind, but in some places, this hidden is not complete: * The internal branch number will appear in the CVS log (LOG) file. * You cannot use the symbolic branch name for "CVS Admin". You can use the admin command to reassign a symbolic name of a RCS hope for a branch. If R4PATCHES is a name "NumBers.c" assigned to branch 1.4.2 (internal branch number is 1.4.0.2), you can use the following command: $ cvs admin -nr4patches: 1.4.2 NumBers.c It will It is only valid when at least one version has been submitted to this branch. Please be very careful not to assign a mark (tag) to an error identification number (now I don't see how the deadline yesterday is assigned). -------------------------------------------------- -------------------------------- 5.6 Merge a whole branch you can merge a branch to your work directory in "Update "-J branch number" in the command. Use the "-j branch number" to merge this derived branch point and the latest version of the latest version of the latest version to your work directory "join".

Let's examine the tree below: ---- ----- --- --- ! 1.1! ----! 1.2! --- -! 1.3! ----! 1.4! <- Bunk ---- --- ---- --- !!! ---- ----- -------- R1FIX branch -> -! 1.2.2.1! ----! 1.2.2.2! ------- -------- Branch 1.2.2 Assign a Rifix's name. The following example assumes that the module "MOD" contains only one file "MC" $ CVS Checkout Mod Mod MOD # get the latest version 1.4 $ CVS Update - J R1Fix MC # merges all changes in the branch, namely: 1.2 and 1.2.2.2 # work directory for this file. $ cvs commit -m "include R1Fix # Create a conflict when the 1.5 version can conflict If this happens, you can resolve it before submitting a new version. Please refer to Section 10.3 [Conflict]. If your original file contains keywords (see Chapter 12 [Keywords]). You You may get more conflict information than strict conflicts. See Section 5.10 [Mergers and Keywords] To learn how to avoid this problem. The "checkout" command also supports the use of "-j" parameters. The following example The examples used above have the effects. $ Cvs checkout -j r1fix mod. $ Cvs commit -m "included R1fix" ---------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- ------- 5.7 Multiple merges from a branch. Continue us above the example. Now this tree looks like this: ---- ----- ---- - --- ----- ! 1.1! ----! 1.2! ----! 1.3! ----! 1.4! ----! 1.5! <- --- ----- --- --- ---- ! *! *! --------- ------- R1FIX branch -> -! 1.2.2.1! ----! 1.2.2.2! -------- - ------ As discussed above, the "*" "" * "guided by branch 1.2.2.2 indicates the merger from RIFIX branch to the backbone.

Now let's continue to develop Rifix branches: ---- ----- -- ----- ---- ! 1.1! ----! 1.2! ------! 1.3! ----! 1.4! ----! 1.5! <- Carne ---- ----- ---- - - --- ----- ! *! *! ------- -------- -------- R1Fix Branch -> -! 1.2.2.1! ----! 1.2.2.2! ----! 1.2.2.3! ------- --------- ------- Then you may want to merge new changes to the backbone. If you still use "CVS Update -j Fifix M.C" CVS will try to merge you have incorporated something, this may write something that does not want to happen. Therefore, you must express it clear that you want to mean only the content that has not been merged. This requires two "-j" parameters. CVS combines from the first "-j" version to the second "-j" version of the "-j" version. For example, in our example: CVS Update -j 1.2.2.2 -j R1Fix MC If the problem occurs, you need to manually specify the version number of 1.2.2.2, a better way is to use: CVS Update -j R1Fix: Yesterday -j R1FIX MC However, a better way is to re-put a latter to the Rifix branch after each merge, then use the tab: cvs update -j merged_from_rifix_to_trunk -j R1Fix MC ---------- -------------------------------------------------- -------------------------- 5.8 combined with two arbitrary versions of the two "-j" signs, this Update (and Checkout The command can merge two any different versions to your work directory. $ cvs update -j 1.3 backend.c will return the 1.5 version to version 1.3, so you must pay attention to the order of the version. If you use this option while operating multiple files, you must understand between different files, the number of versions may be completely different. You must use the laundry (TAG) instead of using the version number to complete the operation of multiple files. Use two "-j" operations can also resume addressed or deleted files. For example, assume you have a file called "file1" in version 1.1, then you remove it in version 1.2, how to operate below: $ cvs update -j 1.2 -j 1.1 file1 file1 $ cvs commit - M Test Checking In File1; / TMP / CVS-Sanity / CVSROOT / First-DIR / FILE1 FILE1, V New Revision: 1.3; Previous Revision: 1.2 Done $ ---------------- -------------------------------------------------- ------------------ 5.9 Merging can add and delete files If you change the change in merge involve adding or deleting some files, "Update -j" will reflect these changes.

For example: CVS Update -a Touch ABC CVS Add ABC; CVS Ci -m "Added" ABC CVS Tag -b BranchTAG CVS Update -R Branchtag Touch D; CVS Add D RM A; CVS RM A CVS Ci -m "Added D, Removed a "CVS Update -a CVS Update -j branchage after these commands (Note To commit), the file A will be deleted, and the file D will be added to the backbone. -------------------------------------------------- ---------------------------------- 5.10 Mergers and Keywords If you merge the file contains keywords (see Chapter 12 [Keywords], 73), you usually get countless conflict reports at the time of consolidation, as you are very different in different versions. Therefore, you often need to use "-kk" when you merge (see Section 12.4 [Alternate Mode], page 75) selection. With keyword names, not to extend the value of the keyword, this feature ensures that your merger is the same, but avoids conflict. For example: Suppose you have a file as follows: ------- BR1 -> -! 1.1.2.1!! ------- !! -- - --- ! 1.1! ----! 1.2! ----- ---- and your current work directory copy is the main (1.2 version). Then, the following merge will produce a result of conflict. Please see: $ cat file1 key $ revision: 1.3 $ ... $ cvs update -j br1 u file1 rcs file: / cvsroot / first-dir / file1, v retrieving revision 1.1 Retrieving Revision 1.1.2.1 Megging Difference Between 1.1 and 1.1.2.1 Into file1 rscmerge: warning: conflicts during merge $ cat file1 $ <<<<<< File1 Key $ Revision: 1.3 $ ======= KEY $ RERISION: 1.1.2.1 $ $ >>>> >>> 1.1.2.1 ... Conflict occurs when trying to merge 1.1 and 1.1.2.1 into your working catalog. Therefore, when this keyword comes from "Revision: 1.1" to "Revision: 1.1.2.1", CVS will try to merge this change to your work directory, this is conflict with the change in your directory "Revision: 1.2" .

The following is used: "- KK": $ Cat File1 Key $ Revision: 1.3 $ ... $ cvs update -kk -j br1 v file1 rcs file: / cvsroot / first-dir / file1, v retrieving revision 1.1 Retrieving Revision 1.1.2.1 Merging Differences Between 1.1 and 1.1.2.1 Into file1 $ cat file1 key $ revision: 1.3 $ ... This version "1.1" and "1.1.2.1" are expanded to pure "revision", so There will be no conflict when merged. However, using the "-kk" parameter is also a major problem. That is, it uses the keyword extension mode commonly used by CVS. In special cases, if the mode uses the "-kb" parameter for binary files. This will have a problem. Therefore, if you include binary files in your database, you will have to handle these questions without using "-kk". More than 10 developers work at the same time -------------------- When multiple developers participate in a project, they often conflicts. The general situation often occurs is that two people want to edit a file at the same time. One of its solution is that the file lock or uses the reserved Checkout, which allows a file to allow only one by one. This is the only solution for some version control systems, including RCS and SCCS. Methods now using the reserved Checkout in CVS are using the "CVS Admin-1 command (see A-6-1Ab [Admin Selection]). Here, this is not a good intelligence solution, when it is a way to use it. The following will also describe the use of the appropriate method to avoid two people to edit a file, not the way of using software to achieve this. The default method in CVS is "unreserved checkout" - non-reserved export. Under this method, developers can edit a file in their work copy. There is no automatic method of the first submission work. You can know that another person is editing the file. Another person may get an error message at an attempt to submit. They must use the CVS command to keep their work to copy the content of the warehouse update. This operation is automatic. CVS can support a variety of different communication mechanisms in Facilitate, without forcing to comply with certain rules, such as "Rensed Checkouts". The following sections describe how these different ways work, and some of the problems involved in multiple methods. 10.1 File Status Based on your operations used by your exported files, and these files have been used in the warehouse, we can divide a file into several states. This state can be obtained by the "status" command, which is: up-to-date: For this branch being used, the file is consistent with the final version in the warehouse. Locally Modified: You modified the file, but no "commit".

Locally added: Use the "add" to add files, but no "commit" locally remoded: You use the "Remove" command, but no "commit" Needs Checkout: Others submit an updated version. The name of this state is somewhat misleading, you should use "Update" instead of "Checkout" to update the new version. NEEDS PATCH: Like "Needs Checkout", the CVS service will only give the Patch (patch) file, not the entire file. The effect of giving PATCH and gives the entire file is the same. Needs Merge: Some people submit a newer version, but you have modified these files. File Had Conflicts On Merge: This is the "local modified" phase, just a conflict information. If you have not resolved conflicts, you need to solve this problem, resolve conflicts, see Section 10.3 [Conflict examples]. Unkown: CVS does not know about this file. For example, you created a new file, not use "Add" commands to help make the status of the file, "Status" also reports the work version (which version is from which version is reported, and also reports "repository vevision". This is the final version of this version of this file in the warehouse. The selection item of the "status" command is in Appendix B [Invoking CVS]. For information on "Sticky Tag" and "Sticky Date" output content, see 4.9 [Sticky Tags]. See the "-k" selection of "STICKY OPTIONS" output, A.16.1 [Update Selection]. You should let the "Update" and "status" commands come together. You use "Update" to update your file to the latest state, you use the "status" command to get the "update" command will do what will do. (Of course, the status in the warehouse will change before you run Update). In fact, if you want to use a command to get status information in use, you can use: $ cvs -n -q -update here "-n" selection means that you don't really perform Update, and only display status; The "-q" selection indicates that the name of each directory is not printed. See Appendix B [Use CVS] for more accommodation on the "Update" command. 10.2 Make a file to the most. When you want to update or merge one, use the update command.

转载请注明原文地址:https://www.9cbs.com/read-228.html

New Post(0)