This is a multi-part answer because there are two separate issues here that are tangling together now. Here’s a summary of what we’ll cover:
mainvsmastererror: src refspec main does not match any- reconciling separate
mainandmasterbranches
Each of these is in its own section.
main vs master
Git itself has no special branch names.1 You could use main, master, trunk, or any other name as the name of your first branch. Git has traditionally used the name master here, but there is a project to make this configurable, so that if you are French or Spanish you can use the name principal or première or primero, or if you prefer Maori, you can use matua or tuatahi. Currently, you can do this manually during or after a git init,2 but the project makes Git just do it automatically, without requiring a second step: If for any reason you want any other name by default, you can configure that.
Meanwhile, GitHub have already chosen to leap ahead and make their default initial branch name main instead of master. But this leaves your Git and GitHub’s Git out of sync, as it were. For more about GitHub’s changeover, see
Difference Between Main Branch and Master Branch in Github?
1There are some technical flaws in this kind of claim. As we know, technically correct is the best kind of correct, so let me add a few caveats in this footnote:
-
Merging auto-generates a message of the form
merge branch X into Ywhen you are on branchYand rungit merge X. However, when you’re onmaster, Git traditionally generates only a message of the formmerge branch X. -
A new, empty repository created by
git inithas no commits and therefore has no branches (because a branch can only exist by having commits on it). However, you must be on some branch in this new empty repository. So Git stores some name in the symbolic ref namedHEAD. This is the branch name that you’re on, even if that branch name does not exist (yet). For a long time, Git has had, hard-coded into it, some code to stick the branch namemasterin there. (This is, in effect, what GitHub changed.) -
There are a bunch of other string literals reading
masterin the source and documentation as well; they’re being converted to use the configuration settings but this will all take time.
2If you have Git 2.28 or later, run git init --initial-branch=name, and/or set init.defaultBranch with git config in your system or global configuration. If you have an earlier version of Git installed, or have already run git init, simply use git branch -m to rename master to whatever name you like.
error: src refspec main does not match any
This error message from Git is quite cryptic to newbies, but is actually pretty simple. The problems are that it’s loaded with jargon (webster; wikipedia), and abbreviates «source» to «src».
Git is all about commits. When we clone a repository, we have our Git reach out to some other Git. That other Git looks up a repository, and that other repository is full of commits. We then have our Git create a new repository locally, transfer into it all of their commits, and turn all of their branch names into remote-tracking names. Then our Git creates, in this new repository, one branch name, based on one of their branch names. At least, that’s the normal process. (And, if you know what all these terms mean, good! If not, don’t worry too much about them right now. The point to remember here is that we get all their commits and none of their branches, and then we normally have our Git create one branch to match one of theirs.)
Since Git is all about commits, this process—of copying all their commits, but only copying one of their branch names to a name spelled the same in our own repository—is all we need. The fact that our Git renames all of their branch names—so that with the one exception, we don’t have any branches at all—isn’t normally very important. Our own Git deals with this later, automatically, if and when it’s necessary.
When we use git push, we are asking our Git program, which is reading our own Git repository, to connect to some other Git program—typically running on a server machine—that can then write to some other Git repository. We’d like our Git to send their Git some of our commits. In particular, we want to send them our new commits: the ones we just made. Those are, after all, where we put all our good new stuff. (Git is all about commits, so that’s the only place we can put anything.)
Once we’ve sent these commits, though, we need to their Git to set one of their branch names to remember our new commits. That’s because the way Git finds commits is to use branch names.3 The real names of each commit are big ugly hash ID numbers, which nobody wants to remember or look at; so we have Git remember these numbers using the branch names. That way, we only have to look at the branch names, and these names can be meaningful to us: trunk, or feature/tall, or tuatahi, or whatever.
By default and convention, the way we do this using git push is pretty simple:
git push origin main
for instance. The git push part is the command that means send commits and ask them to set a name. The origin part is what Git calls a remote: a short name that, mostly, holds a URL. The main part at the end, here, is our branch name. That’s the one our Git is using to find our commits. We’ll have our Git send our commits, then ask their Git to set their main too.
This last part—where we’ve put in main here—is what Git calls a refspec. Refspecs actually let us put in two names, separated by a colon, or a couple of other forms. We can, for instance, use HEAD:main as in Arka’s answer (although for technical reasons we might want to use HEAD:refs/heads/main in many cases). But in simple cases, we can just use one branch name: git push origin main. The simple branch name is a simple form of refspec.
For this to work, the source name must be the name of an existing branch in our own Git repository. This is where things are going wrong.
(See also Message ‘src refspec master does not match any’ when pushing commits in Git)
3Git can use any name, not just a branch name. For instance, a tag name works fine. But this answer is about branch names because the question is about branch names, and branch names are the most common ones to use here.
What if our Git created only master?
Suppose we’re using GitHub and we’ve asked GitHub to make a new repository for us. They run a form of git init that supplies, as the new repository’s initial branch name, the name main. They may or may not create one commit, too. Let’s say we do have them create this one commit. That one commit will hold README and/or LICENSE files, based on what we choose using the web interface. Creating that initial commit actually creates the branch name main.
If we now clone their repository, we’ll get their one commit, which will be under their branch name main. Our Git will rename their main to origin/main and then create one new branch name, main, to match theirs. So all will be good.
But, if we create our own empty Git repository, using git init ourselves, our Git may set us up so that our first commit will create the name master. We won’t have a main branch: we’ll have a master branch instead.
Or, if we don’t have GitHub create an initial commit, the GitHub repository will be totally empty. Because it has no commits, it has no branches: a branch name is only allowed to exist if it specifies some commit. So if we clone this empty repository, we’ll have no branches either, and our Git won’t know to use main: our Git may instead use master. We’re back in that same situation, where our Git think the first name to create should be master.
So, in these various situations, we make our first commit(s), and they all go on a branch named master. If we now run:
git push -u origin main
(with or without the -u; I won’t go into the details about the -u here) our Git looks around in our Git repository for a branch named main. There isn’t one! So our Git just gives us that:
error: src refspec main does not match any
error message.
To fix this, we can either git push origin master—which sends our commits and then asks GitHub to create a new branch in the GitHub repository, with that branch name being master—or rename our master to whatever name we wanted, and then use that name:
git branch -m master xyzzy
git push -u origin xyzzy
will make the (single) branch name that we both use be xyzzy. If you want main here, rename your master to main.
What if you’ve accidentally made both branches?
Suppose we used GitHub to create a new repository, with their new default branch name main, that includes one initial commit with the usual README and LICENSE files. Then, without thinking about it, we used git init on our own machine to create our own new repository, with its default branch name master, and we made a commit or two on our master.
If we now rename our master to main:
git branch -m master main
and then try to push:
git push -u origin main
we get a different error:
! [rejected] main -> main (non-fast-forward)
The reason for this is simple enough: They have a commit, that they find using their name main, that we do not have. If they change their name main to find the last commit that we’re sending them, they’ll lose the initial commit they made, with the README and LICENSE files.
You have a bunch of options here:
-
You can ignore the initial commit they made. It’s just a boilerplate commit, after all. You can tell them to throw it away entirely. Use
git push --forceas outlined in any of many existing StackOverflow answers. -
You can obtain their initial commit and rebase your commits on those commits. This can be slightly tricky, because your first commit is a root commit. If your first commit contains README and/or LICENSE files, you’ll get an add/add conflict here. In this case it’s probably simpler to just force-push.
-
You can obtain their initial commit and merge your commits. In a modern Git, this requires using the
--allow-unrelated-historiesoption. As with the rebase method, if your commits contain README and/or LICENSE files, you’ll get add/add conflicts. The resulting repository will also have two root commits. None of these are serious problems, but they might prove slightly annoying.
To obtain their commit, simply run git fetch origin. That will get GitHub’s first commit, and use the name origin/main in your own Git repository to remember it. You can then:
git rebase origin/main
or:
git merge --allow-unrelated-histories origin/main
to achieve the rebase or merge. You can choose whether to rename your branch to main, if you have not already done so, at any time before or after doing all of this.
Sometimes, Git can’t make your change to a remote repository without losing commits. When this happens, your push is refused.
If another person has pushed to the same branch as you, Git won’t be able to push your changes:
$ git push origin main
> To https://github.com/USERNAME/REPOSITORY.git
> ! [rejected] main -> main (non-fast-forward)
> error: failed to push some refs to 'https://github.com/USERNAME/REPOSITORY.git'
> To prevent you from losing history, non-fast-forward updates were rejected
> Merge the remote changes (e.g. 'git pull') before pushing again. See the
> 'Note about fast-forwards' section of 'git push --help' for details.
You can fix this by fetching and merging the changes made on the remote branch with the changes that you have made locally:
$ git fetch origin
# Fetches updates made to an online repository
$ git merge origin YOUR_BRANCH_NAME
# Merges updates made online with your local work
Or, you can simply use git pull to perform both commands at once:
$ git pull origin YOUR_BRANCH_NAME
# Grabs online updates and merges them with your local work

- →
В предыдущей статье мы прошли базовые команды Git, которые применяются в повседневной работе. В этой публикации продолжим изучение данного инструмента, рассмотрев типичные ошибки при его использовании, а также способы их исправления.
Данная статья не ставит перед собой цель быть энциклопедией решений на все случаи жизни. Было бы неверным давать ответы на вопросы, которые на данном этапе изучения Git просто не могут возникнуть. Любая информация должна соответствовать вашему текущему уровню.
1. Самое простое решение многих проблем
Вы «натворили делов» со своим репозиторием, и вам кажется, что все сломалось и ничего не работает. В качестве максимально быстрого решения этой проблемы можно удалить локальный репозиторий (скрытую папку .git в корне вашего проекта) и репозиторий на GitHub, а затем выполнить git init. При этом ваши файлы удалять не нужно.
Когда я изучал Git, то десятки раз создавал и удалял свои репозитории, сталкиваясь с неразрешимыми для меня на тот момент проблемами.
Этот вариант имеет право на существование для начинающих разработчиков, т. к. они не обладают еще нужным набором знаний для применения более технологичных решений. Но, как вы понимаете, данный способ хорош до поры до времени.
2. Как изменить URL удаленного репозитория?
Вы неверно назвали свой репозиторий, например, вместо StartJava почему-то написали Lesson1 или JavaOps. На что наставник вам сказал, что его нужно переименовать.
Или вы удалили свой репозиторий на GitHub, а у себя на компьютере — оставили. После этого создали новый удаленный репозиторий (УР), изменив его первоначальное имя.
Например, URL репозитория выглядел так:
https://github.com/ichimax/lesson1.git
А после изменений ссылка стала следующей:
https://github.com/ichimax/startjava.git
При этом в настройках локального репозитория (ЛР) адрес старого репозитория никуда не делся — его нужно обновить.
Свяжем ЛР с новым адресом УР:
> git remote set-url origin новый_url.git
> git remote -v
Когда вам в дальнейшем потребуется выполнить push, то необходимо будет написать полную версию команды git push -u origin master, чтобы заново связать ЛР с новым УР, а затем снова можете использовать сокращенный вариант.
3. Как удалить файл из репозитория?
3.1. Удаление файла из индекса
Представим, что вы забыли занести в .gitignore правило, которое позволяло бы игнорировать class-файлы. В итоге применив команду git add, добавили их случайно в индекс.
Это очень частая ошибка у начинающих, которая влечет за собой попадание мусорных файлов в УР.
Скомпилируем исходник, создав class-файл:
Внесем изменения в класс из предыдущих статей:
import java.util.Scanner;
public class MyFirstApp {
public static void main(String[] args) {
System.out.println("У какого языка программирования следующий слоган:");
System.out.print(""Написано однажды, ");
System.out.println("работает везде!"");
String answer = new Scanner(System.in).next();
if (answer.equalsIgnoreCase("Java")) {
System.out.println("Вы угадали");
} else System.out.println("Увы, но - это Java");
}
}
Далее введем привычные команды:
> git add . && git status
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: MyFirstApp.class
modified: MyFirstApp.java
MyFirstApp.class в итоге попал в индекс Git. Необходимо его оттуда удалить, т. к. отслеживание изменений у данного вида файлов не несет никакой практической пользы.
Воспользуемся командой, подсказанной Git:
> git restore --staged MyFirstApp.class && git status
Changes to be committed:
modified: MyFirstApp.java
Untracked files:
MyFirstApp.class
MyFirstApp.class снова стал неотслеживаемым, а измененный класс остался в индексе не тронутым.
Чтобы обезопасить себя, перед использованием команды git add, всегда нужно просматривать список файлов (git status), которые вы планируете добавить в индекс. Также обязательно добавьте шаблон *.class в .gitignore, чтобы больше не спотыкаться о class-файлы.
3.2. Удаление файла из коммита
Пойдем дальше и научимся удалять MyFirstApp.class из коммита.
> git status
Changes to be committed:
new file: MyFirstApp.class
modified: MyFirstApp.java
Добавим все изменения в коммит:
> git commit -m "Добавил quiz по слогану Java"
Перед тем, как запушить коммит, программист решил посмотреть, какие файлы в него входят:
> git log -1 --name-only --oneline
ead5167 (HEAD -> master) Добавил quiz по слогану Java
src/MyFirstApp.class
src/MyFirstApp.java
С командной git log мы уже сталкивались в предыдущей статье. Из нового — аргумент —name-only, который позволяет вывести только имена измененных файлов, находящихся в коммите.
Использование log позволило заметить, что MyFirstApp.class оказался в коммите. Его нужно оттуда убрать.
> git reset --soft HEAD~1
Разберем эту команду по частям:
- reset — отменяет коммиты
- —soft — позволяет выполнить отмену коммита без потери изменений
- HEAD — указатель на локальную ветку в которой мы находимся. В нашем случае HEAD~1 указывает на первый коммит в дереве коммитов ветки master
Более подробно про команду reset (1, 2).
Тут следует сказать, что HEAD указывает на ветку, в которой вы находитесь в данный момент. Благодаря ему мы можем перемещаться по дереву коммитов и откатываться к любому из них.
Получается следующая картина: HEAD указывает на ветку master, а master является указателем на вершину в дереве коммитов.
Отобразим, куда указывает HEAD:
* обозначается текущая ветка.
Если команду ввести с параметром -v, то кроме названия ветки отобразится информация о коммите, на который указывает master:
> git branch -v
* master b59d871 Изменил вывод текста, отображаемого в консоль
После отмены коммита отобразим список оставшихся коммитов:
> git log --oneline
b59d871 (HEAD -> master, origin/master) Изменил вывод текста, отображаемого в консоль
39ba195 Переименовал about.txt в README.md и внес в него описание проекта
1e36e0f Инициализация проекта
Видим, что благодаря reset последний коммит из него был исключен.
При этом log отображает ту же самую информацию, о которой мы говорили выше: HEAD указывает на master, а он — на вершину дерева коммитов (коммит b59d871).
Стоит отметить, что команду reset необходимо использовать только для отмены коммитов, которые находятся исключительно на вашем компьютере и еще не попали на УР. Т. к. эта команда меняет историю коммитов, то это может принести множество проблем для других людей, которые совместно с вами работают в одном репозитории, если вы отмените с ее помощью коммит, а затем запушите изменения на УР.
Посмотрим, в каком состоянии теперь находится ЛР:
> git status
Changes to be committed:
new file: MyFirstApp.class
modified: MyFirstApp.java
Что делать дальше, вы уже знаете: нужно убрать из индекса class-файл, и закоммитить java-класс.
Исключаем MyFirstApp.class:
> git restore --staged MyFirstApp.class
> git status
Changes to be committed:
modified: MyFirstApp.java
Untracked files:
MyFirstApp.class
И тут вы понимаете, что забыли, как у вас назывался отмененный коммит: изменения остались все те же, значит, придумывать описание к коммиту нет смысла — нужно воспользоваться тем, которое было раньше.
Есть одна волшебная команда git reflog, которая отобразит все, что вы когда-либо сделали в своем репозитории с коммитами. Это своего рода лог всех ваших операций. Приведу его малую часть, которая нам необходима:
> git reflog
b59d871 (HEAD -> master, origin/master) HEAD@{0}: reset: moving to HEAD~1
ead5167 HEAD@{1}: commit: Добавил quiz по слогану Java
Из вывода видно описание отмененного коммита. Используем его для нового:
> git commit -m "Добавил quiz по слогану Java"
Больше подробностей о reflog по ссылке.
Не забудьте добавить *.class в.gitignore.
3.3. Удаление файла с GitHub
Самый неприятный случай — это когда мусорный файл все же пробрался на GitHub, т. е. был запушен:

В этом случае наставник вам может написать замечание: «на GitHub не должно быть файлов с расширением *.class, только *.java. Необходимо удалить из УР все class-файлы».
Самый простой выход из этой ситуации — это удалить в ЛР class-файлы, добавить в .gitignore маску *.class и сделать новый пуш. После этих действий на GitHub class-файл удалится. Он также автоматически удалится и у всех людей, которые работают с вами в одном репозитории. Например, когда наставник перед проверкой вашего ДЗ сделает git pull, то удаленные вами class-файлы, удалятся автоматически и у него.
Выглядеть это может примерно так:
D:JavaStartJava (master -> origin)
> git rm src*.class
rm 'src/MyFirstApp.class'
> git status
On branch master
Changes to be committed:
new file: .gitignore
deleted: src/MyFirstApp.class
> git commit -m "Добавил .gitignore с маской *.class"
[master 4bf0ddd] Добавил .gitignore с маской *.class
2 files changed, 1 insertion(+)
create mode 100644 .gitignore
delete mode 100644 src/MyFirstApp.class
> git push

4. Как изменить описание коммита?
4.1. Коммит не был запушен
Вы сделали коммит, но еще его не запушили. Выясняется, что описание к нему содержит опечатку или это сообщение нужно изменить. Разберем данную ситуацию.
Внесем ряд изменений в файл MyFirstApp.java, добавив в него код, запрашивающий у участника квиза его имя, которое будет выводиться, если он ответит правильно на вопрос:
import java.util.Scanner;
public class MyFirstApp {
public static void main(String[] args) {
Scanner console = new Scanner(System.in, "cp866");
System.out.print("Введите, пожалуйста, свое имя: ");
String name = console.next();
System.out.println("У какого языка программирования следующий слоган:");
System.out.print(""Написано однажды, ");
System.out.println("работает везде!"");
String answer = console.next();
if (answer.equalsIgnoreCase("Java")) {
System.out.println(name + ", вы угадали!");
} else System.out.println("Увы, но - это Java");
}
}
> git add MyFirstApp.java
> git commit -m "Добавил ввод имени учасника"
Выясняется, что описание содержит опечатку в слове «учасника».
Для исправления воспользуемся двумя вариантами команды commit:
- в первом случае при вводе git commit —amend, откроется редактор для изменения сообщения:

Такой способ подходит для исправления многострочных комментариев. Нам же больше подходит второй способ.
- во втором случае команда ниже позволит внести изменение прямо из консоли:
> git commit --amend -m "Добавил ввод имени участника"
[master 96e2847] Добавил ввод имени участника
Убедимся, что описание к коммиту изменилось, а прежнее — не сохранилось, отобразив сокращенную информацию по последнему коммиту:
> git log --oneline -1
96e2847 (HEAD -> master) Добавил ввод имени участника
Следует обратить внимание на то, что данные способы позволяют внести изменение в описание только последнего коммита.
4.2.1. Принудительная перезапись истории
Что описание к коммиту нужно изменить, вы вспомнили, когда он был уже отправлен на GitHub.
Чтобы решить эту задачу, необходимо к команде из предыдущего пункта добавить git push -f, которая принудительно перезапишет коммит с ошибочным описанием — исправленным:
> git commit --amend -m "Добавил ввод имени участника"
> git push -f
Среди прочего, в консоли отобразится примерно следующая строка:
+ 5aa3d6d...ce3cf6f master -> master (forced update).
Она сообщает, что было сделано принудительное обновление репозитория.
У ваших коллег (или наставника) после ввода git pull отобразятся строки, тоже сообщающие о принудительном изменении и последующем успешном слиянии (merge):
+ 5aa3d6d...ce3cf6f master -> origin/master (forced update)
Merge made by the 'ort' strategy.
5. Как выполнить пуш, если Git не дает это сделать?
Представим, что на первых порах вы еще не до конца освоили Git и какое-то время вносили изменения в файлы прямо на GitHub. Но рано или поздно поняли, что для своего профессионального роста все же нужно изучить базовые команды Git, и применять их в консоли.
После этого у себя на компьютере начали писать код очередного домашнего задания, а затем решили его запушить на GitHub для проверки наставником. Но сделать пуш у вас в итоге не получилось, а в консоли отобразилась ошибка:
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
Возможна и другая ситуация, когда вы пушите в один репозиторий на GitHub с разных компьютеров. Например, днем, в свободное от работы время, порешали домашку, а затем запушили ее на удаленный репозиторий. Вечером, придя домой, продолжили писать код для следующего ДЗ. А про код, запушенный на GitHub, либо забыли, либо подумали, что из-за него проблем не будет. Но в действительности оказалось все иначе.
Или на GitHub случайно попали class-файлы и вы без задней мысли пошли на сайт и удалили их.
Во всех этих ситуациях пуш приведет к одной и той же ошибке, связанной с тем, что истории изменений на локальном и удаленном репозитории пошли разными путями: на GitHub есть коммит, которого нет в ЛР. В дереве коммитов на ЛР на какое-то количество коммитов меньше, чем на УР.
Научимся решать эту проблему.
5.1. Подтягивание изменений с GitHub
Зайдя в свой репозиторий на GitHub, я внес в README.md следующие мелкие изменения:
- добавил картинку в виде шапки
- пункт «Командная строка» заменил на конкретное название используемой программы — cmder
- добавил иконки к каждому пункту списка
В качестве описания к коммиту указал следующий текст:

При этом README.md содержит следующий код:
# [StartJava](https://topjava.ru/startjava) -- курс на Java для начинающих

## Используемые на курсе инструменты и технологии
:coffee: Java
:octocat: Git/GitHub
:pager: cmder
:bookmark_tabs: Sublime Text
:fire: Intellij IDEA
:gem: SQL
:elephant: PostgreSQL
:newspaper: psql
Проделанные только что изменения я благополучно забыл подтянуть на свой компьютер с помощью git pull. И продолжил работать над классом MyFirstApp.java в ЛР, добавив в него еще один квиз и немного мелких правок.
В итоге класс (у меня на компьютере, не в GitHub) стал выглядеть так:
import java.util.Scanner;
public class MyFirstApp {
public static void main(String[] args) {
Scanner console = new Scanner(System.in, "cp866");
System.out.print("Введите, пожалуйста, свое имя: ");
String name = console.nextLine();
System.out.println("n1. У какого языка программирования следующий слоган:");
System.out.print(""Написано однажды, ");
System.out.println("работает везде!"");
String answer = console.nextLine();
if (answer.equalsIgnoreCase("Java")) {
System.out.println(name + ", вы угадали!");
} else System.out.println("Увы, но - это Java");
System.out.println("n2. Какая фамилия у автора языка Java?");
answer = console.nextLine();
if (answer.equals("Гослинг") || answer.equals("Gosling")) {
System.out.println(name + ", вы угадали!");
} else System.out.println("Увы, но - это Гослинг (Gosling)");
}
}
Добавил изменения в коммит:
> git add MyFirstApp.java
> git commit -m "Добавил quiz по автору Java"
Отобразим полученный результат в консоли:
> git log --oneline -1
7106587 (HEAD -> master) Добавил quiz по автору Java
А теперь самое интересное: попробуем сделать push:
> git push
To https://github.com/ichimax/startjava2.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://github.com/ichimax/startjava2.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Отобразилась ошибка, означающая, что в локальном и удаленном репозитории истории изменений пошли разными путями и не соответствуют друг другу.
Для решения этой проблемы Git предлагает выполнить команду pull, которая подтянет коммиты с УР, а затем объединит их с локальными, чтобы выровнять историю:
> git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 1.16 KiB | 62.00 KiB/s, done.
From https://github.com/ichimax/startjava2
ce3cf6f..2bdecf7 master -> origin/master
Merge made by the 'ort' strategy.
README.md | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
В этом сообщении стоить обратить внимание на строку Merge made by the ‘ort’ strategy. Из нее мы можем сделать вывод, что произошло слияние (merge).
Слияние — это объединение истории коммитов из разных веток в одну. У нас ветка хоть и одна (master), но история коммитов на GitHub и в ЛР стала с какого-то момента различаться. Из-за этого и не удавалось сделать push. Когда мы выполнили git pull, то Git автоматически объединил (что бывает не всегда) последний коммит из УР с последним коммитом из ЛР, создав новый.
Не всегда Git может выполнить слияние автоматически, что вызывает конфликт слияния. Такое бывает, когда в разных ветках был изменен один и тот же фрагмент кода. Из-за этого Git не сможет определить, какую версию использовать. Для решения проблемы потребуется вмешательство пользователя. Более подробно об этом можно узнать по ссылке.
Для того, чтобы минимизировать возникновение подобных ситуаций (конфликтов), рекомендуется каждый раз перед началом работы с проектом делать git pull, чтобы синхронизировать историю коммитов ЛР с историей УР.
Отобразим 4 последних коммита:
> git log --oneline -4
1b4a7b7 (HEAD -> master) Merge branch 'master' of https://github.com/ichimax/startjava2
7106587 Добавил quiz по автору Java
2bdecf7 (origin/master) Обновил README.md
ce3cf6f Добавил ввод имени участника
Из этого списка видно, что:
2bdecf7 — был сделан на GitHub
7106587 — был сделан в ЛР
1b4a7b7 — получился автоматически после слияния двух предыдущих коммитов
Обратите внимание, что у коммита, сделанного на GitHub, ветка называется не master, а origin/master. Разница в том, что master — это имя локальной ветки, а origin/master является удаленной веткой с именем master.
Отобразим ветки, связанные с нашим репозиторием:
> git branch -a
* master
remotes/origin/master
Ветка master является текущей (помечена *) веткой ЛР. remotes/origin/master — это ветвь с именем master и псевдонимом origin на УР.
То, что это — разные ветки, можно убедиться визуально, введя следующую команду:
D:JavaStartJavasrc (master -> origin)
> git log --pretty=format:"%h - %s" --graph
* 1b4a7b7 - Merge branch 'master' of https://github.com/ichimax/startjava2
|
| * 2bdecf7 - Обновил README.md
* | 7106587 - Добавил quiz по автору Java
|/
* ce3cf6f - Добавил ввод имени участника
* 4bf0ddd - Добавил .gitignore с маской *.class
* 90ca67c - Добавил quiz по слогану Java
* b59d871 - Изменил вывод текста, отображаемого в консоль
* 39ba195 - Переименовал about.txt в README.md и внес в него описание проекта
* 1e36e0f - Инициализация проекта
Опция —graph позволяет вывести граф в формате ASCII, который показывает текущую ветку и историю слияний. Более подробно с разными опциями команды log можно ознакомиться по ссылке.
Давайте взглянем на различия в последних коммитах в удаленной и локальной master-ветках:
D:JavaStartJavasrc (master -> origin)
> git diff origin/master..master
diff --git a/src/MyFirstApp.java b/src/MyFirstApp.java
index 8e25560..08099ad 100644
--- a/src/MyFirstApp.java
+++ b/src/MyFirstApp.java
@@ -4,15 +4,22 @@ public class MyFirstApp {
public static void main(String[] args) {
Scanner console = new Scanner(System.in, "cp866");
System.out.print("Введите, пожалуйста, свое имя: ");
- String name = console.next();
+ String name = console.nextLine();
- System.out.println("У какого языка программирования следующий слоган:");
+ System.out.println("n1. У какого языка программирования следующий слоган:");
System.out.print(""Написано однажды, ");
System.out.println("работает везде!"");
- String answer = console.next();
+ String answer = console.nextLine();
if (answer.equalsIgnoreCase("Java")) {
System.out.println(name + ", вы угадали!");
} else System.out.println("Увы, но - это Java");
+
+ System.out.println("n2. Какая фамилия у автора языка Java?");
+
+ answer = console.nextLine();
+ if (answer.equals("Гослинг") || answer.equals("Gosling")) {
+ System.out.println(name + ", вы угадали!");
+ } else System.out.println("Увы, но - это Гослинг (Gosling)");
}
}
После всех манипуляций отобразим состояние репозитория:
> git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
Посмотрим, какие два коммита мы должны запушить:
> git log --branches --not --remotes --oneline
1b4a7b7 (HEAD -> master) Merge branch 'master' of https://github.com/ichimax/startjava2
7106587 Добавил quiz по автору Java
Выполним push и снова введем команду, отображающую список из 4 коммитов:
> git push
> git log --oneline -4
1b4a7b7 (HEAD -> master, origin/master) Merge branch 'master' of https://github.com/ichimax/startjava2
7106587 Добавил quiz по автору Java
2bdecf7 Обновил README.md
ce3cf6f Добавил ввод имени участника
Видим, что история коммитов выровнялась: HEAD в ЛР и УР указывают на самый последний коммит 1b4a7b7.
Список решений тех или иных задач с помощью Git, разобранных в статье, с кратким описанием.
В статье мы рассмотрели самые простые, но часто возникающие проблемы, которые могут появиться при работе с Git и GitHub. Это базовый минимум, который поможет вам на первых порах не чувствовать себя растерянным, столкнувшись лицом к лицу с описанными сложностями.
Оцените статью, если она вам понравилась!
![]()
![]()
|
fatal: No such remote ‘origin’ |
|
fatal: No such remote ‘origin’
fatal: No such remote ‘origin’
Скорее всего Вы пытаетесь выполнить
$ git remote set-url origin https://github.com/name/project.git
Попробуйте сперва выполнить
$ git remote add origin https://github.com/name/project.git
2
To https://github.com/YourName/yourproject.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to ‘https://github.com/YourName/yourproject.git’
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: ‘git pull …’) before pushing again.
hint: See the ‘Note about fast-forwards’ in ‘git push —help’ for details.
Скорее всего Вы пытаетесь выполнить
git push origin master
в новом репозитории.
При этом, когда
Вы создавали удалённый репозиторий на github Вы отметили опцию initialize with readme file.
Таким образом на удалённом репозитории файл
README.md
есть, а на локальном нет. Git не
понимает как такое могло произойти и предполагает, что на удалённый репозиторий кто-то (возможно Вы)
добавил что-то неотслеженное локальным репозиторием.
Первым делом попробуйте
$ git pull origin master
$ git push origin master
Git скачает файл
README.md
с удалённого репозитория и затем можно будет спокойно пушить
Если сделать pull не получилось, например, возникла ошибка
From https://github.com/andreiolegovichru/heiheiru
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
Попробуйте
$ git pull —allow-unrelated-histories origin master
$ git push origin master
ERROR: Permission to AndreiOlegovich/qa-demo-project.git denied to andreiolegovichru.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Возможная причина — git не видит ваш ключ. Либо ваш ключ уже используется для другого удалённого
хранилища.
Решить можно удалив стандарный ключ id_rsa.pub создать новую пару и добавить на удалённое хранилище.
Если этот способ не подходит — нужно настроить config.