(
self,
base: ghstack.git.CommitHeader,
base_diff_meta: Optional[DiffMeta],
diff: ghstack.diff.Diff,
elab_diff: Optional[DiffWithGitHubMetadata],
submit: bool,
)
| 913 | ) |
| 914 | |
| 915 | def process_commit( |
| 916 | self, |
| 917 | base: ghstack.git.CommitHeader, |
| 918 | base_diff_meta: Optional[DiffMeta], |
| 919 | diff: ghstack.diff.Diff, |
| 920 | elab_diff: Optional[DiffWithGitHubMetadata], |
| 921 | submit: bool, |
| 922 | ) -> Optional[DiffMeta]: |
| 923 | # Do not process poisoned commits |
| 924 | if "[ghstack-poisoned]" in diff.summary: |
| 925 | self._raise_poisoned() |
| 926 | |
| 927 | # Do not process closed commits |
| 928 | if elab_diff is not None and elab_diff.closed: |
| 929 | if self.direct: |
| 930 | self._raise_needs_rebase() |
| 931 | # If we're trying to submit a closed commit, check if it has been modified |
| 932 | if elab_diff.remote_source_id is None: |
| 933 | # The branch was deleted (e.g., after landing). Check if the commit has been |
| 934 | # modified by comparing source_ids. If the commit is reachable from master with |
| 935 | # the same source_id (tree hash), it means it was landed and we should skip it. |
| 936 | # Otherwise, it's been modified and we should raise an error. |
| 937 | try: |
| 938 | # Check if there's a commit on master with the same tree (source_id) |
| 939 | master_commits = self.sh.git( |
| 940 | "log", |
| 941 | "--format=%H %T", |
| 942 | f"{self.remote_name}/{self.base}", |
| 943 | "-n", |
| 944 | "100", # Check last 100 commits |
| 945 | ) |
| 946 | for line in master_commits.split("\n"): |
| 947 | if not line.strip(): |
| 948 | continue |
| 949 | commit_hash, tree_hash = line.split() |
| 950 | if tree_hash == diff.source_id: |
| 951 | # Found a commit on master with the same tree, so this commit |
| 952 | # was landed (just with a different commit message/hash) |
| 953 | return None |
| 954 | except Exception: |
| 955 | pass |
| 956 | # Didn't find a matching commit on master, so this is a modified closed commit |
| 957 | raise RuntimeError( |
| 958 | f"Cannot ghstack a stack with closed PR #{elab_diff.number} whose branch was deleted. " |
| 959 | "If you were just trying to update a later PR in the stack, `git rebase` and try again. " |
| 960 | "Otherwise, you may have been trying to update a PR that was already closed. " |
| 961 | "To disassociate your update from the old PR and open a new PR, " |
| 962 | "run `ghstack unlink`, `git rebase` and then try again." |
| 963 | ) |
| 964 | elif diff.source_id != elab_diff.remote_source_id: |
| 965 | # The commit has been modified locally |
| 966 | raise RuntimeError( |
| 967 | f"Cannot ghstack a stack with closed PR #{elab_diff.number} whose branch was deleted. " |
| 968 | "If you were just trying to update a later PR in the stack, `git rebase` and try again. " |
| 969 | "Otherwise, you may have been trying to update a PR that was already closed. " |
| 970 | "To disassociate your update from the old PR and open a new PR, " |
| 971 | "run `ghstack unlink`, `git rebase` and then try again." |
| 972 | ) |
no test coverage detected