Perforce Public Knowledge Base - Backing out a changelist after multiple subsequent changes
Reset Search
 

 

Article

Backing out a changelist after multiple subsequent changes

« Go Back

Information

 
Problem
How do I back out of a particular changelist without losing subsequent submitted changes?
Solution
Sometimes a bad changelist is submitted.  If you respond in time, you can back out that changelist using the method described in Backing Out Submitted Changelists using P4V. With super privileges, the strategic use of p4 obliterate can also undo a submission.  The obliterate approach is especially recommended on a new, accidental integrations as seen in How to Rollback an Integration.

However, there are times when a bad changelist is submitted and many further changes have subsequently been submitted.  In that case, it is possible to create a new version of the files without the bad changelist. Creating a new file without the bad change(s) is accomplished by merging the file to a new branch before the bad changelist, then merging the bad changelist but resolving with an ignore, and then merging in the rest of the good changelists. Below is an example using a file with 15 lines, 4 revisions, and a bad revision #3 that we want to remove.

Ignoring a particular version

1. Suppose we have four revisions where revision 3 is undesired.

            Original file submitted in changelist 24760

$ p4 print a.txt#1
//depot/main/release1/perl_proj/a.txt#1 - add change 24760 (text)
1                                                                
2                                                                
3                                                                
4                                                                
5                                                                
6                                                                
7                                                                
8                                                                
9                                                                
10                                                               
11                                                               
12                                                               
13                                                               
14                                                               
15

Add 2a, delete 5, and modify 12 in changelist 24761

$ p4 print a.txt#2
//depot/main/release1/perl_proj/a.txt#2 - edit change 24761 (text)
1                                                                 
2                                                                 
2a                                                                
3                                                                 
4                                                                 
6                                                                 
7                                                                 
8                                                                 
9                                                                 
10                                                                
11
12a
13
14
15

Add 1b, delete 7, modify 14 in changelist 24762 (Bad change)
 
$ p4 print a.txt#3
//depot/main/release1/perl_proj/a.txt#3 - edit change 24762 (text)
1
1b
2
2a
3
4
6
8
9
10
11
12a
13
14b
15

Add 3c, delete 10, modify 15 in changelist 24763
 
$ p4 print a.txt#4
//depot/main/release1/perl_proj/a.txt#4 - edit change 24763 (text)
1
1b
2
2a
3
3c
4
6
8
9
11
12a
13
14b
15c

The third changelist is the bad one we want to eliminate.
Note that undesired 1b was added, 7 was deleted, and 14 was modified.
But we want all the other changes such as 3c added, 10 deleted, and 15 modified.

2. Integrate revision 1 only to the new branch

We integrate the revision 1 only to a new branch using a typical resolve.  Note "#1,1".  This means from revision 1 to revision 1. A range such as #1,2 would indicate from revision 1 to revision 2.

$ p4 integrate a.txt#1,1 ../../release2/perl_proj/a.txt
//depot/main/release2/perl_proj/a.txt#1 - branch/sync from //depot/main/release1/perl_proj/a.txt#1

$ p4 submit -d "new a.txt to work with"
Submitting change 24764.                                            
Locking 1 files ...                                                 
branch //depot/main/release2/perl_proj/a.txt#1                      
Change 24764 submitted.                                             

3. Integrate revision 2 only to the new branch.

Note that we use #2,2 to integrate only the changes of revision 2 and none of the changes introduced in revision 1. We resolve with a typical resolve.

$ p4 integrate a.txt#2,2 ../../release2/perl_proj/a.txt
//depot/main/release2/perl_proj/a.txt#1 - integrate from //depot/main/release1/perl_proj/a.txt#2

$ p4 resolve                                                       
/home/perforce/p4work/main/release2/perl_proj/a.txt - merging //depot/main/release1/perl_proj/a.txt#2
Diff chunks: 0 yours + 3 theirs + 0 both + 0 conflicting                                                                                                      
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) at: at                                                     
//main/release2/perl_proj/a.txt - copy from //depot/main/release1/perl_proj/a.txt
               
$ p4 submit -d "good changes from version 2 integrated"
Submitting change 24765.                                                            
Locking 1 files ...                                                                 
integrate //depot/main/release2/perl_proj/a.txt#2                                   
Change 24765 submitted.                                                             

            Note that steps 2 and 3 could have been combined as
            "p4 integrate a.txt#1,2 ../../release2/perl_proj/a.txt"

4. Integrate revision 3 only to the new branch but with an "ignore"
     Use resolve -ay to complete the integration but not incorporate the changes in revision 3.  Note "#3,3" specifies the range of revision 3 to revision 3.
 
$ p4 integrate a.txt#3,3 ../../release2/perl_proj/a.txt
//depot/main/release2/perl_proj/a.txt#2 - integrate from //depot/main/release1/perl_proj/a.txt#3
 
$ p4 resolve
/home/perforce/p4work/main/release2/perl_proj/a.txt - merging //depot/main/release1/perl_proj/a.txt#3
Diff chunks: 0 yours + 3 theirs + 0 both + 0 conflicting
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) at: ey                                                     
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) at: et                                                     
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) at: ay                                                     
//main/release2/perl_proj/a.txt - ignored //depot/main/release1/perl_proj/a.txt
                  
$ p4 submit -d "ignoring bad changes from third revision"
Submitting change 24766.
Locking 1 files ...
integrate //depot/main/release2/perl_proj/a.txt#3
Change 24766 submitted.

5. Integrate revision 4 only to the new branch
Resolve normally.  Note "#4,4" to indicate only propagating revision 4.
We also optionally set the P4MERGE variable to show a graphical merge.
 
$ p4 integrate a.txt#4,4 ../../release2/perl_proj/a.txt
//depot/main/release2/perl_proj/a.txt#3 - integrate from //depot/main/release1/perl_proj/a.txt#4


$ export P4MERGE=/home/perforce/p4work/20133/p4v-2013.3.712190/bin/p4merge

$ p4 resolve
/home/perforce/p4work/main/release2/perl_proj/a.txt - merging //depot/main/release1/perl_proj/a.txt#4
Diff chunks: 3 yours + 3 theirs + 0 both + 0 conflicting
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) am: m
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) am: am
//main/release2/perl_proj/a.txt - merge from //depot/main/release1/perl_proj/a.txt

$ p4 submit -d "submitting with ignored #3"
Submitting change 24767.
Locking 1 files ...
integrate //depot/main/release2/perl_proj/a.txt#4
Change 24767 submitted.

 
6.  Check the resulting merge

In our example, we wanted to see lines 1 through 15
Then add 2a, delete 5, and modify 12
Then 3c, delete 10, modify 15
But skip: add 1b, delete 7, modify 14
 
$ cat /home/perforce/p4work/Perl/main/release2/perl_proj/a.txt
1
2
2a
3
3c
4
6
7
8
9
11
12a
13
14
15c


Note that this works well because all the changes made were clearly separated from other parts of the code.  If there were changes back to back, there may be conflicts where a manual resolve would be required.

 

Ignoring a particular changelist

We can do the same integration operations using changelists instead of revision numbers.  

In the example below, we create a version that encompasses all changes before the bad changelist. 

A. In this example, let us keep changelists from 24760 to 24761.


$ p4 integrate //depot/main/release1/perl_proj/...@24760,24761 //depot/main/release2/perl_proj/...
//depot/main/release2/perl_proj/a.txt#1 - branch/sync from //depot/main/release1/perl_proj/a.txt#1,#2
                          
$ cat /home/rfong/p4work/Randall_Perl/main/release2/perl_proj/a.txt
1                                                                                               
2                                                                                               
2a                                                                                              
3                                                                                               
4                                                                                               
6                                                                                               
7                                                                                               
8                                                                                               
9                                                                                               
10                                                                                              
11                                                                                              
12a                                                                                             
13                                                                                              
14                                                                                              
15
                                                                                              
$ p4 submit -d "cherry-pick changelists 24760 and 24761 to release2"
Submitting change 24769.                                                                         
Locking 1 files ...                                                                              
branch //depot/main/release2/perl_proj/a.txt#1                                                   
Change 24769 submitted.                                                                          
                                                                    
B. Ignore the bad changelist 24762 but resolve using the "ay" option, that is, ignore.
                                                         
$ p4 integrate //depot/main/release1/perl_proj/...@24762,24762 //depot/main/release2/perl_proj/...
//depot/main/release2/perl_proj/a.txt#1 - integrate from //depot/main/release1/perl_proj/a.txt#3
                               
$ p4 resolve                                                                                      
/home/rfong/p4work/main/release2/perl_proj/a.txt - merging //depot/main/release1/perl_proj/a.txt#3                
Diff chunks: 0 yours + 3 theirs + 0 both + 0 conflicting                                                                       
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) at: ay                                                                     
//Perl/main/release2/perl_proj/a.txt - ignored //depot/main/release1/perl_proj/a.txt                                   

$ p4 submit -d "Ignoring bad change 24762"
Submitting change 24770.                                               
Locking 1 files ...                                                    
integrate //depot/main/release2/perl_proj/a.txt#2                      
Change 24770 submitted.                                                                   

Notice that there is no change on the target destination.  But now Perforce knows to ignore this changelist.
 
$ p4 print //depot/main/release2/perl_proj/a.txt
//depot/main/release2/perl_proj/a.txt#2 - integrate change 24770 (text)      
1                                                                            
2                                                                            
2a                                                                           
3                                                                            
4                                                                            
6                                                                            
7                                                                            
8                                                                            
9                                                                            
10
11
12a
13
14
15

C. Integrate the remaining changelists and resolve as usual

We now can merge all the subsequent changelists that took place after the bad changelist.  In this example, there is only one changelist 24763 to merge.
 
$ p4 integrate //depot/main/release1/perl_proj/...@24763,24763 //depot/main/release2/perl_proj/...
//depot/main/release2/perl_proj/a.txt#2 - integrate from //depot/main/release1/perl_proj/a.txt#4

$ echo $P4MERGE
/home/perforce/p4work/20133/p4v-2013.3.712190/bin/p4merge

$ p4 resolve
/home/perforce/p4work/Perl/main/release2/perl_proj/a.txt - merging //depot/main/release1/perl_proj/a.txt#4
Diff chunks: 3 yours + 3 theirs + 0 both + 0 conflicting
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) am: m
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) am: am
//Randall_Perl/main/release2/perl_proj/a.txt - merge from //depot/main/release1/perl_proj/a.txt

$ p4 submit -d "Integrating subsequent changelists after skipping bad changelist"
Submitting change 24771.
Locking 1 files ...
integrate //depot/main/release2/perl_proj/a.txt#3
Change 24771 submitted.

D. Integrating by changelist instead of revision still produces the same results as above to ignore the bad changelist.

$ p4 print //depot/main/release2/perl_proj/a.txt
//depot/main/release2/perl_proj/a.txt#3 - integrate change 24771 (text)
1
2
2a
3
3c
4
6
7
8
9
11
12a
13
14
15c
$
Related Links

Feedback

 

Was this article helpful?


   

Feedback

Please tell us how we can make this article more useful.

Characters Remaining: 255