Ok, I think I found what is going on. I did have a look at your online repo at gitlab.
The top commit in your main branch
https://gitlab.com/aruna.hewapathirane/lazarus/-/commits/main is
Commit dd428486
authored 5 Dec 2022, 15:50 by Aruna Hewapathirane's avatar Aruna Hewapathirane
Merge remote-tracking branch 'upstream/main'
And if you look at the graph
https://gitlab.com/aruna.hewapathirane/lazarus/-/network/main (you have to scroll down a bit),
you will find that this merge contains your working branch (ending with Commit 9db84220 "Delete Laz_Hello.lpi")
So you did do commits to the "main" branch.
And you pushed them.
And that is why you are getting errors.
But before I get into detail, a bit of background and some other info.
Steps to fix are at the end of this post. So you can skip forward
1) "git log --graph --oneline"For some reason your output does not contain any branch/tag names at all. Here is what I get (and what afaik should be default).
You can see some lines start with "(" and then branch names. (on the console this usually is colored).
- So the commit on the first line is at "HEAD" which points to the branch "main_gitlab".
It also is at origin/main and origin/HEAD
- The 2nd line is at "main" (that is my local main branch)
* cbef44b7ef (HEAD -> main_gitlab, origin/main, origin/HEAD) CodeTools: fix attribute resolver - remove exception handling
| * 4190c37981 (main) DebuggerOptions, EnvironmentOptions: move class-config
| * e215aa22c2 EnvironmentOptions: When saving data, don't destroy any existing xml. (if data on disk changed)
|/
* 0f438c98fe CodeTools: fix attribute resolver
This allows me to quickly see where the "tips" of all my branches are.
2) "branch" / "tip" or "head" of a branch .... (nomenclature)Maybe worth, making sure we talk about the same thing....
The (English) word "branch" is used for a variety of things.
It can be
- A series of commits known by the branch name (i.e. all the commits that "git log <branchname>" will show)
Mind that the branch starts at the very first commit of the repo.
Not at the "fork-point" (where the branch was created / diverts from another branch).
So some (older) commits on a branch are usually shared with other branches
- A reference to the "branchname"
- The "tip" (sometimes also "head of") of the branch. That is the latest commit made to the branch.
This is the commit on which "git log" will display the branch-name
3) "branch" local vs remote (vs "distributed")There exists more than one "branch" called "main".
(And the same is true for most other branches / well any branch that is pushed/pulled to/from a remote)
* All the below is using "main". But applies to any other branch that exists on a remote.
You can have a git repo without remote (only your local copy). Then you only have one "main" branch.
You commit to it, and the tip of main will be on the new commit.
Now if you have a remote, the remote may have 3 commit in main (left = oldest)
REMOTE:
A - B - C (main)If you clone/pull that remote to a local repo:
- then your local repo will remember that the remote has "main" on "C". ("origin" in the example is the name of the remote)
- your local repo will create a local main branch on the same commit. (or it will be created when you switch/checkout to it)
LOCAL
A - B - C (main, origin/main)If you make a commit to "main" you make it locally. So it affects your local branch.
Both:
- The series of commits. As you have one more commit
- The "tip" of the branch. As it move forward
LOCAL (with your commit)
A - B - C (origin/main) - D (main)As you can see, your local repo still has a memory where the remote has (or maybe had) the tip of its branch.
If you
push then you send all the commits that you added to the remote.
=> Well, if all goes as expected.
But what if someone else pushed to the remote...If someone else pushed to the remote, then you don't have that persons commit.
REMOTE (with someone's commit):
A - B - C - E (main)LOCAL (with your commit)
A - B - C (origin/main) - D (main)So now there are 3 versions of the main branch.
1) Your local "main"
2) Your local last-know-remote "origin/main"
3) the actual remote "main"
Unlike SVN which will merge at the server, git will not accept your push.
GIT always requires that you do the merging yourself.
To be precise:
Git requires that your "origin/main" and the actual remote's "main" are the same, in order for you to push.So the push then can just add the new commits you made, to the tip of the remote. And the remote will be 100% the same as your local copy.
(Mind, your local repo has 2 remotes. So it has to memorized-remote branches upstream/main and personal/main)
4) "git pull" and trackingThe local branch usually knows to which remote branch it belongs. (called tracking).
That is, your local branch does not have to have the same name, it could be called anything. In most cases such relationships are defined by tracking (usually set at creating time, or when first pushing). The name only matters in a few cases.
REMOTE (with someone's commit):
A - B - C - E (main)LOCAL (without any commit by you)
A - B - C (main, origin/main)Now if you do "git pull" it will get the commit "E". And the "origin/main" will be pointing to that (since it will be the last we have seen on the remote).
In this case your local "main" will also be changed. It will be "fast forwarded" (i.e. it will move forward to the commit E).
(Note that fast-forward is considered a "merge", even though there is no merge-commit)
But in case of
REMOTE (with someone's commit):
A - B - C - E (main)LOCAL (with your commit)
A - B - C (origin/main) - D (main)You get
LOCAL (after pull - before any update to your local "main")
A - B - C - E (origin/main)
\ - D (main)The (versions of the) "main" branch have "diverged" => they are no longer in a straight line.
"git pull" will by default merge them. It will create a Merge commit "F":
(And that is what happened to you)
A - B - C - E (origin/main) - F (main)
\ - D - /=>
Avoiding merge commits by pull "git config pull.ff only"
https://wiki.freepascal.org/SVN_to_GIT_Cheatsheet#RecommendedAnd then "git rebase" or configure pull to do the rebase => check the git manpages.
5) The error you gotNow your pushed the above merge commit to your forked remote "personal"....
But that commit is not in our Lazarus git repo.
You local branch "main" is tracking our remote main.
- So "git pull upstream" will affect the local "main".
- "git pull personal" will not affect the local "main"
Anyway your your remote "personal" main now has a commit (the merge) that is not in our remote "upstream" main.
And your local "main" is "up to date" with "upstream/main" (your git status said so).
So your local main does
not contain the merge commit (including all your commits that were merged) that you pushed to "personal".
And that means you can't push this commit to personal.
6) Fixing your situation...(and make sure you change "git pull" as above)
You want "personal/main" to be an exact copy of our "upstream/main".
So you need to move your commits to a new branch.
a) create the new branch.
git branch my-diverged-main main Creating my-diverged-main to replace "main" (because we later move/reset "personal/main", and then the new branch makes sure all your commits are kept)
git branch my-work 9db8422087ac5c156d5d20f8c20feaf329f65ae2 The sha1 is from your online repo (but will be the same in your local repo). It is the "Delete Laz_Hello.lpi" commit
You now have a branch "my-work" on that commit.
Create any other branches you may need for any local commits you have made since (i.e. not yet pushed)
git push --set-upstream personal my-diverged-main git push --set-upstream personal my-workNow you have your work on your remote. As a new branch.
Check that gitlab shows this
Pushing my-diverged-main is optional. It only contains the merge-commit, which likely you will not need.
b) change/correct personal/main git push --force-with-lease personal mainThis will override the remote branch.
That is, the current "main" on the upstream remote will be replaced (deleted) by the new "main" as it is in your local repo (and that is up to date with upstream).
Mind, it only "deletes" the old location (tip). of the branch.
The commits will remain, because you created new branches that also contain the new commits.
If you had not created those new branches, then the commits would become unreachable.
Once fixed, and assuming you do not add your own commits to main again, then you will not need the "force with lease" again. It should work with just
git push personal main
8) git switch vs git checkoutIf your have a current version of git, I recommend you look up "git switch" and use it instead of "git checkout".
But it's a personal decision.
See the wiki page that I linked.