~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ngit/NGit/NGit.Api/RebaseCommand.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
42
*/
43
43
 
 
44
using System;
44
45
using System.Collections.Generic;
45
46
using System.IO;
46
47
using System.Text;
102
103
 
103
104
                private static readonly string ONTO = "onto";
104
105
 
 
106
                private static readonly string ONTO_NAME = "onto-name";
 
107
 
105
108
                private static readonly string PATCH = "patch";
106
109
 
107
110
                private static readonly string REBASE_HEAD = "head";
119
122
 
120
123
                private RevCommit upstreamCommit;
121
124
 
 
125
                private string upstreamCommitName;
 
126
 
122
127
                private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
123
128
 
124
129
                private readonly RevWalk walk;
141
146
                /// this method twice on an instance.
142
147
                /// </summary>
143
148
                /// <returns>an object describing the result of this command</returns>
144
 
                /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
145
 
                /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
146
 
                /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
147
 
                /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
 
149
                /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
 
150
                ///     </exception>
 
151
                /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException
 
152
                ///     </exception>
 
153
                /// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException
 
154
                ///     </exception>
 
155
                /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
 
156
                ///     </exception>
148
157
                public override RebaseResult Call()
149
158
                {
150
159
                        RevCommit newHead = null;
172
181
                                        case RebaseCommand.Operation.CONTINUE:
173
182
                                        {
174
183
                                                // fall through
175
 
                                                string upstreamCommitName = ReadFile(rebaseDir, ONTO);
176
 
                                                this.upstreamCommit = walk.ParseCommit(repo.Resolve(upstreamCommitName));
 
184
                                                string upstreamCommitId = ReadFile(rebaseDir, ONTO);
 
185
                                                try
 
186
                                                {
 
187
                                                        upstreamCommitName = ReadFile(rebaseDir, ONTO_NAME);
 
188
                                                }
 
189
                                                catch (FileNotFoundException)
 
190
                                                {
 
191
                                                        // Fall back to commit ID if file doesn't exist (e.g. rebase
 
192
                                                        // was started by C Git)
 
193
                                                        upstreamCommitName = upstreamCommitId;
 
194
                                                }
 
195
                                                this.upstreamCommit = walk.ParseCommit(repo.Resolve(upstreamCommitId));
177
196
                                                break;
178
197
                                        }
179
198
 
238
257
                                                        // TODO if the content of this commit is already merged
239
258
                                                        // here we should skip this step in order to avoid
240
259
                                                        // confusing pseudo-changed
 
260
                                                        string ourCommitName = GetOurCommitName();
241
261
                                                        CherryPickResult cherryPickResult = new Git(repo).CherryPick().Include(commitToPick
242
 
                                                                ).Call();
 
262
                                                                ).SetOurCommitName(ourCommitName).Call();
243
263
                                                        switch (cherryPickResult.GetStatus())
244
264
                                                        {
245
265
                                                                case CherryPickResult.CherryPickStatus.FAILED:
292
312
                        }
293
313
                }
294
314
 
 
315
                private string GetOurCommitName()
 
316
                {
 
317
                        // If onto is different from upstream, this should say "onto", but
 
318
                        // RebaseCommand doesn't support a different "onto" at the moment.
 
319
                        string ourCommitName = "Upstream, based on " + Repository.ShortenRefName(upstreamCommitName
 
320
                                );
 
321
                        return ourCommitName;
 
322
                }
 
323
 
295
324
                /// <exception cref="System.IO.IOException"></exception>
296
325
                private void UpdateHead(string headName, RevCommit newHead)
297
326
                {
336
365
 
337
366
                /// <exception cref="System.IO.IOException"></exception>
338
367
                /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
339
 
                /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
340
368
                private RevCommit CheckoutCurrentHead()
341
369
                {
342
370
                        ObjectId headTree = repo.Resolve(Constants.HEAD + "^{tree}");
462
490
                        // representation for date and timezone
463
491
                        sb.Append(GIT_AUTHOR_DATE);
464
492
                        sb.Append("='");
 
493
                        sb.Append("@");
 
494
                        // @ for time in seconds since 1970
465
495
                        string externalString = author.ToExternalString();
466
496
                        sb.Append(Sharpen.Runtime.Substring(externalString, externalString.LastIndexOf('>'
467
497
                                ) + 2));
563
593
                        }
564
594
                }
565
595
 
566
 
                /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
567
596
                /// <exception cref="System.IO.IOException"></exception>
568
 
                /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
569
 
                /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
 
597
                /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
570
598
                private RebaseResult InitFilesAndRewind()
571
599
                {
572
600
                        // we need to store everything into files so that we can implement
629
657
                        Sharpen.Collections.Reverse(cherryPickList);
630
658
                        // create the folder for the meta information
631
659
                        FileUtils.Mkdir(rebaseDir);
632
 
                        CreateFile(repo.Directory, Constants.ORIG_HEAD, headId.Name);
 
660
                        repo.WriteOrigHead(headId);
633
661
                        CreateFile(rebaseDir, REBASE_HEAD, headId.Name);
634
662
                        CreateFile(rebaseDir, HEAD_NAME, headName);
635
663
                        CreateFile(rebaseDir, ONTO, upstreamCommit.Name);
 
664
                        CreateFile(rebaseDir, ONTO_NAME, upstreamCommitName);
636
665
                        CreateFile(rebaseDir, INTERACTIVE, string.Empty);
637
666
                        BufferedWriter fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream
638
667
                                (new FilePath(rebaseDir, GIT_REBASE_TODO)), Constants.CHARACTER_ENCODING));
683
712
                ///     </summary>
684
713
                /// <param name="newCommit"></param>
685
714
                /// <returns>the new head, or null</returns>
686
 
                /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
 
715
                /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 
716
                /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
687
717
                ///     </exception>
688
 
                /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
689
718
                public virtual RevCommit TryFastForward(RevCommit newCommit)
690
719
                {
691
720
                        Ref head = repo.GetRef(Constants.HEAD);
718
747
                }
719
748
 
720
749
                /// <exception cref="System.IO.IOException"></exception>
721
 
                /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
 
750
                /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
722
751
                private RevCommit TryFastForward(string headName, RevCommit oldCommit, RevCommit 
723
752
                        newCommit)
724
753
                {
788
817
                        if (this.operation != RebaseCommand.Operation.BEGIN)
789
818
                        {
790
819
                                // these operations are only possible while in a rebasing state
791
 
                                if (repo.GetRepositoryState() != RepositoryState.REBASING_INTERACTIVE)
 
820
                                if (s != RepositoryState.REBASING_INTERACTIVE && s != RepositoryState.REBASING &&
 
821
                                         s != RepositoryState.REBASING_REBASING && s != RepositoryState.REBASING_MERGE)
792
822
                                {
793
823
                                        throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().wrongRepositoryState
794
824
                                                , repo.GetRepositoryState().Name()));
835
865
                {
836
866
                        try
837
867
                        {
838
 
                                string commitId = ReadFile(repo.Directory, Constants.ORIG_HEAD);
 
868
                                ObjectId origHead = repo.ReadOrigHead();
 
869
                                string commitId = origHead != null ? origHead.Name : null;
839
870
                                monitor.BeginTask(MessageFormat.Format(JGitText.Get().abortingRebase, commitId), 
840
871
                                        ProgressMonitor.UNKNOWN);
841
872
                                DirCacheCheckout dco;
945
976
                }
946
977
 
947
978
                /// <exception cref="System.IO.IOException"></exception>
948
 
                private IList<RebaseCommand.Step> LoadSteps()
 
979
                internal virtual IList<RebaseCommand.Step> LoadSteps()
949
980
                {
950
981
                        byte[] buf = IOUtil.ReadFully(new FilePath(rebaseDir, GIT_REBASE_TODO));
951
982
                        int ptr = 0;
955
986
                        {
956
987
                                tokenBegin = ptr;
957
988
                                ptr = RawParseUtils.NextLF(buf, ptr);
958
 
                                int nextSpace = 0;
 
989
                                int nextSpace = RawParseUtils.Next(buf, tokenBegin, ' ');
959
990
                                int tokenCount = 0;
960
991
                                RebaseCommand.Step current = null;
961
992
                                while (tokenCount < 3 && nextSpace < ptr)
964
995
                                        {
965
996
                                                case 0:
966
997
                                                {
967
 
                                                        nextSpace = RawParseUtils.Next(buf, tokenBegin, ' ');
968
998
                                                        string actionToken = Sharpen.Runtime.GetStringForBytes(buf, tokenBegin, nextSpace
969
999
                                                                 - tokenBegin - 1);
970
1000
                                                        tokenBegin = nextSpace;
1023
1053
                public virtual NGit.Api.RebaseCommand SetUpstream(RevCommit upstream)
1024
1054
                {
1025
1055
                        this.upstreamCommit = upstream;
 
1056
                        this.upstreamCommitName = upstream.Name;
1026
1057
                        return this;
1027
1058
                }
1028
1059
 
1036
1067
                        try
1037
1068
                        {
1038
1069
                                this.upstreamCommit = walk.ParseCommit(upstream);
 
1070
                                this.upstreamCommitName = upstream.Name;
1039
1071
                        }
1040
1072
                        catch (IOException e)
1041
1073
                        {
1063
1095
                                                , upstream));
1064
1096
                                }
1065
1097
                                upstreamCommit = walk.ParseCommit(repo.Resolve(upstream));
 
1098
                                upstreamCommitName = upstream;
1066
1099
                                return this;
1067
1100
                        }
1068
1101
                        catch (IOException ioe)
1071
1104
                        }
1072
1105
                }
1073
1106
 
 
1107
                /// <summary>Optionally override the name of the upstream.</summary>
 
1108
                /// <remarks>
 
1109
                /// Optionally override the name of the upstream. If this is used, it has to
 
1110
                /// come after any
 
1111
                /// <see cref="SetUpstream(NGit.Revwalk.RevCommit)">SetUpstream(NGit.Revwalk.RevCommit)
 
1112
                ///     </see>
 
1113
                /// call.
 
1114
                /// </remarks>
 
1115
                /// <param name="upstreamName">the name which will be used to refer to upstream in conflicts
 
1116
                ///     </param>
 
1117
                /// <returns>
 
1118
                /// 
 
1119
                /// <code>this</code>
 
1120
                /// </returns>
 
1121
                public virtual NGit.Api.RebaseCommand SetUpstreamName(string upstreamName)
 
1122
                {
 
1123
                        if (upstreamCommit == null)
 
1124
                        {
 
1125
                                throw new InvalidOperationException("setUpstreamName must be called after setUpstream."
 
1126
                                        );
 
1127
                        }
 
1128
                        this.upstreamCommitName = upstreamName;
 
1129
                        return this;
 
1130
                }
 
1131
 
1074
1132
                /// <param name="operation">the operation to perform</param>
1075
1133
                /// <returns>
1076
1134
                /// 
1108
1166
                                return this.token;
1109
1167
                        }
1110
1168
 
 
1169
                        public override string ToString()
 
1170
                        {
 
1171
                                return "Action[" + token + "]";
 
1172
                        }
 
1173
 
1111
1174
                        internal static RebaseCommand.Action Parse(string token)
1112
1175
                        {
1113
1176
                                if (token.Equals("pick") || token.Equals("p"))
1131
1194
                        {
1132
1195
                                this.action = action;
1133
1196
                        }
 
1197
 
 
1198
                        public override string ToString()
 
1199
                        {
 
1200
                                return "Step[" + action + ", " + ((commit == null) ? "null" : commit.ToString ()) + ", " + ((
 
1201
                                        shortMessage == null) ? "null" : Sharpen.Runtime.GetStringForBytes(shortMessage)
 
1202
                                        ) + "]";
 
1203
                        }
1134
1204
                }
1135
1205
 
1136
1206
                internal virtual PersonIdent ParseAuthor(byte[] raw)
1161
1231
                        string email = keyValueMap.Get(GIT_AUTHOR_EMAIL);
1162
1232
                        string time = keyValueMap.Get(GIT_AUTHOR_DATE);
1163
1233
                        // the time is saved as <seconds since 1970> <timezone offset>
1164
 
                        long when = long.Parse(Sharpen.Runtime.Substring(time, 0, time.IndexOf(' '))) * 1000;
 
1234
                        int timeStart = 0;
 
1235
                        if (time.StartsWith("@"))
 
1236
                        {
 
1237
                                timeStart = 1;
 
1238
                        }
 
1239
                        else
 
1240
                        {
 
1241
                                timeStart = 0;
 
1242
                        }
 
1243
                        long when = long.Parse(Sharpen.Runtime.Substring(time, timeStart, time.IndexOf(' '
 
1244
                                ))) * 1000;
1165
1245
                        string tzOffsetString = Sharpen.Runtime.Substring(time, time.IndexOf(' ') + 1);
1166
1246
                        int multiplier = -1;
1167
1247
                        if (tzOffsetString[0] == '+')