|
21 | 21 | import java.text.MessageFormat;
|
22 | 22 | import java.util.ArrayList;
|
23 | 23 | import java.util.Arrays;
|
| 24 | +import java.util.Collection; |
24 | 25 | import java.util.Collections;
|
25 | 26 | import java.util.Date;
|
26 | 27 | import java.util.HashMap;
|
|
36 | 37 | import org.eclipse.jgit.api.FetchCommand;
|
37 | 38 | import org.eclipse.jgit.api.Git;
|
38 | 39 | import org.eclipse.jgit.api.TagCommand;
|
| 40 | +import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; |
39 | 41 | import org.eclipse.jgit.api.errors.GitAPIException;
|
| 42 | +import org.eclipse.jgit.api.errors.JGitInternalException; |
40 | 43 | import org.eclipse.jgit.diff.DiffEntry;
|
41 | 44 | import org.eclipse.jgit.diff.DiffEntry.ChangeType;
|
42 | 45 | import org.eclipse.jgit.diff.DiffFormatter;
|
43 | 46 | import org.eclipse.jgit.diff.RawTextComparator;
|
| 47 | +import org.eclipse.jgit.dircache.DirCache; |
| 48 | +import org.eclipse.jgit.dircache.DirCacheEntry; |
44 | 49 | import org.eclipse.jgit.errors.ConfigInvalidException;
|
45 | 50 | import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
46 | 51 | import org.eclipse.jgit.errors.LargeObjectException;
|
47 | 52 | import org.eclipse.jgit.errors.MissingObjectException;
|
48 | 53 | import org.eclipse.jgit.errors.StopWalkException;
|
| 54 | +import org.eclipse.jgit.internal.JGitText; |
49 | 55 | import org.eclipse.jgit.lib.BlobBasedConfig;
|
50 | 56 | import org.eclipse.jgit.lib.CommitBuilder;
|
51 | 57 | import org.eclipse.jgit.lib.Constants;
|
|
63 | 69 | import org.eclipse.jgit.lib.TreeFormatter;
|
64 | 70 | import org.eclipse.jgit.merge.MergeStrategy;
|
65 | 71 | import org.eclipse.jgit.merge.RecursiveMerger;
|
| 72 | +import org.eclipse.jgit.merge.ThreeWayMerger; |
66 | 73 | import org.eclipse.jgit.revwalk.RevBlob;
|
67 | 74 | import org.eclipse.jgit.revwalk.RevCommit;
|
68 | 75 | import org.eclipse.jgit.revwalk.RevObject;
|
|
75 | 82 | import org.eclipse.jgit.transport.CredentialsProvider;
|
76 | 83 | import org.eclipse.jgit.transport.FetchResult;
|
77 | 84 | import org.eclipse.jgit.transport.RefSpec;
|
| 85 | +import org.eclipse.jgit.treewalk.CanonicalTreeParser; |
78 | 86 | import org.eclipse.jgit.treewalk.TreeWalk;
|
79 | 87 | import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
|
80 | 88 | import org.eclipse.jgit.treewalk.filter.OrTreeFilter;
|
@@ -2597,4 +2605,127 @@ public static String getLfsRepositoryUrl(String baseURL, String repositoryName,
|
2597 | 2605 | + "objects/" + oid;
|
2598 | 2606 |
|
2599 | 2607 | }
|
| 2608 | + |
| 2609 | + /** |
| 2610 | + * Returns all tree entries that do not match the ignore paths. |
| 2611 | + * |
| 2612 | + * @param db |
| 2613 | + * @param ignorePaths |
| 2614 | + * @param dcBuilder |
| 2615 | + * @throws IOException |
| 2616 | + */ |
| 2617 | + public static List<DirCacheEntry> getTreeEntries(Repository db, String branch, Collection<String> ignorePaths) throws IOException { |
| 2618 | + List<DirCacheEntry> list = new ArrayList<DirCacheEntry>(); |
| 2619 | + TreeWalk tw = null; |
| 2620 | + try { |
| 2621 | + ObjectId treeId = db.resolve(branch + "^{tree}"); |
| 2622 | + if (treeId == null) { |
| 2623 | + // branch does not exist yet |
| 2624 | + return list; |
| 2625 | + } |
| 2626 | + tw = new TreeWalk(db); |
| 2627 | + int hIdx = tw.addTree(treeId); |
| 2628 | + tw.setRecursive(true); |
| 2629 | + |
| 2630 | + while (tw.next()) { |
| 2631 | + String path = tw.getPathString(); |
| 2632 | + CanonicalTreeParser hTree = null; |
| 2633 | + if (hIdx != -1) { |
| 2634 | + hTree = tw.getTree(hIdx, CanonicalTreeParser.class); |
| 2635 | + } |
| 2636 | + if (!ignorePaths.contains(path)) { |
| 2637 | + // add all other tree entries |
| 2638 | + if (hTree != null) { |
| 2639 | + final DirCacheEntry entry = new DirCacheEntry(path); |
| 2640 | + entry.setObjectId(hTree.getEntryObjectId()); |
| 2641 | + entry.setFileMode(hTree.getEntryFileMode()); |
| 2642 | + list.add(entry); |
| 2643 | + } |
| 2644 | + } |
| 2645 | + } |
| 2646 | + } finally { |
| 2647 | + if (tw != null) { |
| 2648 | + tw.close(); |
| 2649 | + } |
| 2650 | + } |
| 2651 | + return list; |
| 2652 | + } |
| 2653 | + |
| 2654 | + public static boolean commitIndex(Repository db, String branch, DirCache index, |
| 2655 | + ObjectId parentId, boolean forceCommit, |
| 2656 | + String author, String authorEmail, String message) throws IOException, ConcurrentRefUpdateException { |
| 2657 | + boolean success = false; |
| 2658 | + |
| 2659 | + ObjectId headId = db.resolve(branch + "^{commit}"); |
| 2660 | + ObjectId baseId = parentId; |
| 2661 | + if (baseId == null || headId == null) { return false; } |
| 2662 | + |
| 2663 | + ObjectInserter odi = db.newObjectInserter(); |
| 2664 | + try { |
| 2665 | + // Create the in-memory index of the new/updated ticket |
| 2666 | + ObjectId indexTreeId = index.writeTree(odi); |
| 2667 | + |
| 2668 | + // Create a commit object |
| 2669 | + PersonIdent ident = new PersonIdent(author, authorEmail); |
| 2670 | + |
| 2671 | + if (forceCommit == false) { |
| 2672 | + ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(db, true); |
| 2673 | + merger.setObjectInserter(odi); |
| 2674 | + merger.setBase(baseId); |
| 2675 | + boolean mergeSuccess = merger.merge(indexTreeId, headId); |
| 2676 | + |
| 2677 | + if (mergeSuccess) { |
| 2678 | + indexTreeId = merger.getResultTreeId(); |
| 2679 | + } else { |
| 2680 | + //Manual merge required |
| 2681 | + return false; |
| 2682 | + } |
| 2683 | + } |
| 2684 | + |
| 2685 | + CommitBuilder commit = new CommitBuilder(); |
| 2686 | + commit.setAuthor(ident); |
| 2687 | + commit.setCommitter(ident); |
| 2688 | + commit.setEncoding(com.gitblit.Constants.ENCODING); |
| 2689 | + commit.setMessage(message); |
| 2690 | + commit.setParentId(headId); |
| 2691 | + commit.setTreeId(indexTreeId); |
| 2692 | + |
| 2693 | + // Insert the commit into the repository |
| 2694 | + ObjectId commitId = odi.insert(commit); |
| 2695 | + odi.flush(); |
| 2696 | + |
| 2697 | + RevWalk revWalk = new RevWalk(db); |
| 2698 | + try { |
| 2699 | + RevCommit revCommit = revWalk.parseCommit(commitId); |
| 2700 | + RefUpdate ru = db.updateRef(branch); |
| 2701 | + ru.setForceUpdate(forceCommit); |
| 2702 | + ru.setNewObjectId(commitId); |
| 2703 | + ru.setExpectedOldObjectId(headId); |
| 2704 | + ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false); |
| 2705 | + Result rc = ru.update(); |
| 2706 | + |
| 2707 | + switch (rc) { |
| 2708 | + case NEW: |
| 2709 | + case FORCED: |
| 2710 | + case FAST_FORWARD: |
| 2711 | + success = true; |
| 2712 | + break; |
| 2713 | + case REJECTED: |
| 2714 | + case LOCK_FAILURE: |
| 2715 | + throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD, |
| 2716 | + ru.getRef(), rc); |
| 2717 | + default: |
| 2718 | + throw new JGitInternalException(MessageFormat.format( |
| 2719 | + JGitText.get().updatingRefFailed, branch, commitId.toString(), |
| 2720 | + rc)); |
| 2721 | + } |
| 2722 | + } finally { |
| 2723 | + revWalk.close(); |
| 2724 | + } |
| 2725 | + } finally { |
| 2726 | + odi.close(); |
| 2727 | + } |
| 2728 | + return success; |
| 2729 | + } |
| 2730 | + |
2600 | 2731 | }
|
0 commit comments