Страницы

Поиск по вопросам

Показаны сообщения с ярлыком git-push. Показать все сообщения
Показаны сообщения с ярлыком git-push. Показать все сообщения

понедельник, 13 апреля 2020 г.

Как правильно откатиться до коммита и залить это на удаленный репозиторий?

#git #git_commit #git_remote #git_push

                    
Есть два репозитория:


голый (bare) репозиторий, из него все берут копию, в нем есть  мастер ветка, которая
всегда соответствует production состоянию
есть локальный репозиторий


Разработчик откатывается к предыдущем коммиту в локальном репозитории git reset --soft,
потом делает коммит, потом пуш.

Пуш отклоняется, разработчик делает пул и мержит локальный мастер и с удаленным,
после чего отмененные строки кода опять встают на место и смысл затеи теряется!

Подскажите, пожалуйста, как правильно откатиться до коммита и залить это на удаленный
репозиторий?
    


Ответы

Ответ 1



Для простоты предположим, что проблемный коммит только один. Чтобы откатить опубликованный (push) коммит, есть два основных пути: git revert номер_проблемного_коммита. Создаёт второй, "противоположный" коммит, "со знаком минус". После его публикации получится состояние, как до проблемного коммита, но в истории останется пара ненужный-коммит + отмена-ненужного-коммита. git push --force. Перед этим нужен git reset, как советуют в комментариях. Эту опцию следует использовать с осторожностью. Рассмотрим следующие случаи: Никто ещё не увидел опубликовынные изменения (в том числе "роботы", которые могут что-то автоматически делать при push'е). Тогда --force наилучший вариант. Несколько человек уже обновились после неудачного коммита. Тогда перед использованием --force следует их уведомить, так как на их стороне --force может "взбаламутить" ситуацию и потребовать дополнительных действий. Если тут же вместо проблемного коммита не положить ещё какой-нибудь другой коммит, то проблемный коммит может снова попасть на сервер (даже без --force'а) от этих разработчиков. Кто-то уже опубликовал изменения поверх неудачного коммита. Тогда --force затрёт их новые коммиты. От этого можно защититься опцией --force-with-lease. В этом случае нужно обновиться и делать git rebase -i, а потом уже --force (причём во время этой операции могут набежать ещё новые коммиты). Тут git revert будет более уместен. Много человек уже обновилось, есть несколько опубликованных или неопубликованных изменений "поверх" плохого коммита: git revert.

Ответ 2



как вариант git reflog - выдаст список HEAD c номерами и описанием, достаточно выбрать интересуещее вас состояние и сделать сброс до этого HEAD. git reset --hard HEAD @{номер} HEAD – это указатель на текущую ветку, которая, в свою очередь, является указателем на последний коммит, сделанный в этой ветке. Это значит, что HEAD будет родителем следующего созданного коммита. Как правило, самое простое считать HEAD снимком вашего последнего коммита.

Ответ 3



В зависимости от платформы, Вы можете написать так: GitHub откат на 1 коммит локально: git reset --hard HEAD~1 Примечание: это потенциально опасная команда, так как она сбрасывает все ваши незафиксированные изменения. Потом удаляете в репозитории удаленно командой: git push origin -f По аналогии на BitBucket откат на 1 коммит локально: git reset --hard HEAD~1 и удаленно командой удаляете: git push -f origin HEAD^:master Примечание: вместо ветки master Вы можете использовать любую другую ветку. Этой командой Вы только удаляете с Bitbucket. HEAD~1 и HEAD^ могут быть взаимозаменяемыми.

Что делать, когда Updates were rejected because the tip of your current branch is behind its remote counterpart

#git #git_push

                    
Делаю git push, получаю следующее сообщение об ошибке.

To git@github.com:name/project.git
   21b430d..dd378ca  master -> master
 ! [rejected]        release -> release (non-fast-forward)
error: failed to push some refs to 'git@github.com:jkubicek/my_proj.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration
hint: variable to 'current' or 'upstream' to push only the current branch.


как я понял, кроме 

git push https://name@site.ru/visit/visit.0.11.git  


туда еще указать свою ветку, как ее указывать надо?
    


Ответы

Ответ 1



Чтобы уже наверняка, сделайте текущую ветку дефолтной (чтобы не промахнуться при пуше): git config --global push.default current Потом верните обратно в мастер. И не забывайте забирать изменения из веток через git fetch

воскресенье, 29 марта 2020 г.

git-push для отдельной директории

#git #github #git_push


Resourse:

Структура проекта

.git
build/
fonts/
node_modules/
src/
.gitignore
gulpfile.js
package.json
package-lock.json


файл .gitignore
Это те файлы, которые мне не нужно отправлять в репо

node_modules/
.idea/
gulpfile.js
package.json
package-lock.json
src/
fonts/
.git/


Summary:
Когда произвожу git push origin push 
почему-то в  репозиторий появляются такая структура

build
fonts
src
.gitginore


Question:

Как же сделать, чтобы отправить только папку build(только содержимое этой папки,
а не саму папку)??
Заранее приношу извинения... Я не особо силен в git
    


Ответы

Ответ 1



Система контроля версий не предназначена для того, чтобы оперировать файлы. Она нужна только для того, чтобы хранить их историю. Всё остальное должны выполнять другие утилиты. Когда Вы делаете коммит, в репозиторий отправляется ровно та структура, которая сейчас есть рядом с .git-файлом, за исключением пустых папок (если в них нет .gitkeep и объектов из .gitignore). Поэтому Вы видите такую структуру. Таким образом, Ваша задача распадается на 2 несколькими способами. Способ 1: Перенести всё из build в основную репу Добавить в коммит только те файлы, которые Вам нужны Сделать коммит Способ 2: Перенести всё из build в основную репу Добавить все файлы, которые Вам НЕ нужны в .gitignore Сделать коммит Способ 3: Создать в build отдельный репозиторий Сделать коммит Как переносить файлы, это дело Ваше. Я предлагаю использовать утилиту make, сделав соответствующее правило. В таком случае, это будет выглядеть более технологично. Отдельно можно обсудить каждый из этих вариантов, но все они выглядят как костыли, поскольку пушить бинарные файлы в репу -- это плохо. Я бы сказал, что это антипаттерн. Бинарные файлы собираются под конкретную архитектуру. Кроме того, человек может легко собрать соответствующий файл сам или забрать из последнего релиза.

воскресенье, 15 марта 2020 г.

Какие изменения происходят на удаленном сервере при git push?

#git #git_push #git_remote


Если я делаю push из локального репозитория в удаленный, то на удаленном файл полностью
изменяется на локальный? Или они сначала сравниваются и заливаются только изменения?
    


Ответы

Ответ 1



Git оперирует не файлами, а коммитами. Коммит — это «снимок» текущего состояния рабочей области. Он содержит полные версии файлов, а не изменения (также называемые дельтами или патчами). Подробнее о коммитах: Каким образом git сохраняет изменившуюся строку при коммите? Или они сначала сравниваются и заливаются только изменения? Отчасти вы правы: они действительно сначала сравниваются. Для сравнения файлов используется алгоритм Secure Hash Algorithm. Когда вы заливаете (push) очередные коммиты на удаленный сервер, Git сравнивает значение sha1 для каждого объекта. Если в его истории уже есть объект для этого значения, то повторно закачиваться он не будет. Если нет — то будет закачана полная версия этого файла, а точнее, содержащий его объект типа blob. на удаленном файл Как уже отметил alexander barakin, ваш удаленный сервер скорее всего типа bare, то есть не содержит файлов в рабочей области (а только внутренние файлы Git-репозитория).

Ответ 2



удалённый репозиторий — скорее всего — bare-репозиторий («голый»), т.е. возле него нет рабочего каталога (working directory), и, соответственно, никаких файлов, которые вы наблюдаете в своём рабочем каталоге. чтобы было понятней: в удалённом репозитории хранится практически то же, что и у вас в каталоге .git возле содержимого вашего рабочего каталога. а это, собственно, и есть git-репозиторий. исходя из вышеизложенного, надеюсь, становится понятно, что вопрос в текущей формулировке просто лишён смысла.

пятница, 13 марта 2020 г.

Клонирование git и push в два репозитория

#git #bitbucket #git_push #git_remote


Создал я локальный репозиторий у себя на компьютере:

cd /path/to/git/repo/
git init --bare --shared


В другом месте тоже инициализировал, с которым работал так, напрямую:

cd /path/to/my/project/
git init
echo "Helo" >> hello.txt
git add .
git commit -m "Init"


Вот теперь я хочу в свой локальный репозиторий сделать пуш:

git remote add origin /path/to/git/repo/
git push origin master


Все хорошо, все отлично. Если запустить эту команду в другой директории, он мне все
скопирует, то есть сделает то, что я ожидаю:

cd /path/to/test/dir/
git clone /path/to/git/repo/


Теперь я хочу:


Все свои собранные коммиты запушить на свежий, только что созданный репозиторий в
bitbucket.org.
Иметь возможность пушить как на битбакет, так и в локальный репозиторий 


Что мне нужно сделать, чтобы добиться такого результата? 

P.S. Отвечая на вопрос, зачем мне нужен локальный репозиторий. Мне нужно всегда иметь
на компьютере копию проекта с учетом всех gitignore. Даже тогда, когда у меня нет интернета.
Если есть возможность провернуть это без создания локального репозитория, можете дать
совет. Но вопрос, как запушить все коммиты на битбакет и не видеть постоянные сообщения
Everything up-to-date и другие, не смотря на то, что на компе у меня лежит целая куча
нужных мне коммитов, остается открытым
    


Ответы

Ответ 1



когда вы сделали git init, вы уже создали локальный репозиторий. он находится в под-каталоге .git. файлы же, которые вы создали в этом каталоге (/path/to/my/project/), а затем с помощью git add и git commit «добавили в репозиторий», на самом деле представляют собой лишь рабочую копию содержимого репозитория. репозиторий может быть и без рабочей копии. создаётся такой репозиторий при использовании опции --bare у команд git clone, git init. фактически вы получаете в таком репозитории то же содержимое, что и в каталоге .git у репозитория с рабочей копией. поэтому создавать ещё одну локальную копию репозитория, как сделали вы в каталоге /path/to/git/repo/, нет необходимости. всё содержимое репозитория, все коммиты, вся история — доступны в любой из копий git-репозитория и без доступа к интернету. и коммиты в эту копию репозитория вы можете делать без доступа к интернету. а как сделать вторую (третью, десятую) копию репозитория на каком-нибудь удалённом сервере, вы уже знаете: $ git remote add ... $ git push ... о том, как одной командой git push отправить изменения сразу в несколько репозиториев, написано, например, здесь и здесь. и по-русски: Отправить изменения в несколько репозиториев одной командой push

воскресенье, 8 марта 2020 г.

развёртывание проекта с помощью git push

#git #git_push


имеется:


сервер с git-ом и доступом по протоколу ssh
на сервере в каталоге /путь/к/ создано обыкновенное (не-bare) git-хранилище командой
git init
у пользователя, от имени которого подключаюсь, есть права на запись в этот каталог


требуется:


чтобы при отправке изменений командой git push в любую ветку из локального клона
этого хранилища обновлённые файлы тут же появлялись на сервере в рабочем каталоге /путь/к/
именно в том виде, как они представленны в этой самой ветке


да, я знаю про подводные камни. меры приняты.

как настроить хранилище на сервере, чтобы оно работало именно так, как мне требуется?
    


Ответы

Ответ 1



на сервере: в каталоге /путь/к/ выполните команду: $ git config receive.denyCurrentBranch ignore в хранилище (/путь/к/.git/) создайте файл /путь/к/.git/hooks/post-update следующего содержания: #!/bin/sh GIT_WORK_TREE=$(dirname $PWD) git reset --hard $(git rev-parse $1) добавьте этому файлу биты исполнимости: $ chmod +x /путь/к/.git/hooks/post-update всё. теперь можете клонировать это хранилище себе локально: $ git clone пользователь@сервер:/путь/к/ добавлять файлы, ветки, коммитить и отправлять изменения на сервер командой git push (понятно, что если ветки на сервере ещё не существует, надо будет её указать, например, так: git push origin ветка). если вдруг понадобится переключиться на другой коммит/ветку без создания нового коммита, то придётся «вручную» на сервере выполнить (в каталоге /путь/к/) git checkout -f ... или git reset --hard ... навеяно этими вопросами (и ответами к ним) с одной целью — упростить процесс: Настройка и развертывание проекта c помощью Git Deploy a project using Git push

Git не делает push на другую ветку на сервере

#git #git_push


$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.

...

$ git push origin Tim_Musharapov
error: src refspec Tim_Musharapov does not match any.
error: failed to push some refs to '...'


Почему не удается сделать push?
    


Ответы

Ответ 1



error: src refspec Tim_Musharapov does not match any Это означает, что в репозитории origin просто нет ветки с именем Tim_Musharapov. Её нужно создать. Для создания веток применяется такой синтаксис: git push origin что:куда Здесь что - это локальная ветка, которую вы хотите запушить, а куда - имя новой ветки на origin, в которую вы хотите запушить ветку что. А origin это название удалённого репозитория (remote), оно может быть другим, но по умолчанию используется такое. Поэтому предложенный в соседнем ответе вариант git push origin master:Tim_Musharapov означает "Взять локальную ветку master и запушить во вновь создаваемую ветку Tim_Musharapov". Это работает, но появится несоответствие в названиях локальных и удалённых веток. А ещё ветка master у вас теперь занята под собственную работу и стало неудобно получать обновления ветки master репозитория origin: Your branch is ahead of 'origin/master' by 3 commits В вашей ветке master есть три ваших коммита, так что git pull в эту ветку уже не получится. Есть общепринятая практика: называть локальные и удалённые ветки одинаково. Это не обязательно (т.е. Git позволяет делать и по-другому), но удобно и практично. Соответственно, если вам нельзя изменять удалённую ветку master то не вносите изменений по ходу работы в локальный master. Поэтому предлагаю такое решение: Для начала нам нужна ветка, в которую будем коммитить результаты своей работы. Она может называться, например, Tim_Musharapov, но обычно ветку называют по решаемой задаче, а не по имени разработчика. Если такой ветки ещё нет, её нужно создать так, чтобы она дублировала master (смотрела на тот же коммит). git checkout -b Tim_Musharapov master Если ветка уже есть, обновим её до текущего master: git checkout Tim_Musharapov git merge --ff-only master # если конфликт, значит там есть какие-то изменения, которых нет в master # нужно смотреть и разбираться. пушим её в origin, ключ -u сохраняет соответствие локальной и удалённой ветки git push -u origin Tim_Musharapov:Tim_Musharapov # в следующий раз из этой ветки можно будет пушить проще: git push А ветку master вернём к состоянию как на remote git checkout master git reset --hard origin/master # В локальную ветку master мы будем получать обновления с origin git checkout master git pull Ещё немного про синтаксис что:куда: git checkout somebranch # Оба варианта создают одноимённую ветку на origin git push origin -u somebranch git push origin -u somebranch: # Запушить "ничего" в ветку - значит удалить её git push origin :otherbranch

Ответ 2



Потому что идет привязка к основной ветке. Делайте так: git push origin master:Tim_Musharapov

четверг, 13 февраля 2020 г.

Потерял текущую ветку с кодом - как восстановить?

#android_studio #git #git_commit #git_push


У меня случился полный пиндец... Целую неделю писал код в Android Studio в базовой
ветке master. Изменения коммитил, но не пушил на сервер.

В итоге, когда собрался запушить на сервер, решил сначала сохранить то что было на
сервере в ветке master в отдельную ветку. Используя инструменты AS, в нижнем правом
углу, выбрал ветку master на сервере, нажал checkOutAs, ввел новое имя "develop/test1"
и нажал enter. После чего проект просто обнулился до состояния сервера, в папке проекта
так же все файлы удалились, и пропала панель Version Control.

Вот последние сообщения в логах:


  12:29 5 files committed: Отказался от использования элементов экшен бара
  
  13:29 1 file committed: Схема базы данных
  
  13:30 Checked out new branch develop/test1 from origin/master (show balloon)


Помогите понять что произошло. И самое главное - как восстановить потерянный код?!
Где-то же дожна была сохраниться история коммитов???
    


Ответы

Ответ 1



У вас все коммиты должны остаться в локальном репозитории. Попробуйте выполнить git reflog, чтобы отобразить список всех сделанных вами коммитов. Если найдете там нужный (последний ваш коммит), то сделайте git checkout 1c7474c, где "1c7474c" - это id нужного коммита.

Ответ 2



Еще один более простой и правильный способ решения проблемы. По каким то непонятным причинам в Android Studio иногда слетает Git, что приводит к вышеописанным проблемам. И на самом деле, ничего переключать и восстанавливать не нужно. Достаточно зайти в меню VSC и нажать Enable version control integration, после чего в появившемся окошке выбрать нужный вариант (в моем случае Git).

понедельник, 10 февраля 2020 г.

Не могу сделать push в чужой репозиторий: “already up-to-date”

#git #git_push


Меня добавили в репозиторий (дали права на коммит, пуш).

Сделал клон этого репозитория, создал ветку, закоммитил изменения.

Пытаюсь сделать git push, чтобы на удалённом появилась моя новая ветка со всеми изменениями.

Ввожу мэйл, пароль, в ответ приходит "already up-to-date". Данных на удаленном нет...

Что я делаю не так?
    


Ответы

Ответ 1



already up-to-date Это означает что: На том сервере, куда вы пушите, уже есть такая ветка И эта ветка находится в таком же состоянии (т.е. точно на тот же коммит смотрит). Варианты: Вы пушите не туда (а в какой-то другой репозиторий). Проверяется командой git remote -v Вы пушите не то что нужно (а например свою ветку master). Предположим, нужные коммиты у вас в ветке mybranch: git checkout mybranch # проверим, что коммиты на месте git log git push -u origin mybranch Можно обойтись без checkout и сразу выбрать, что и куда пушить: git push -u origin mybranch:mybranch Вы сделали коммиты не в ту ветку. создал ветку, закоммитил изменения. Довольно частая ситуация: разработчик создал ветку, но не переключился на неё. Проверяется просто: # проверим, что коммиты на месте git log mybranch Если оказалось, что коммиты, например, в master, а должны быть в mybranch: git checkout mybranch git reset --hard master # теперь пробуем пушить git push -u origin mybranch # а теперь вернём свой master на тот же коммит, который на удалённом сервере git checkout master git reset --hard origin/master # заодно можно его обновить git pull

воскресенье, 9 февраля 2020 г.

Как не потерять локальные изменения, если надо сделать git pull?

#git #git_commit #git_push #git_pull


При попытке запушить код в репозиторий, git ругнулся и сказал, что есть свежие изменения,
а значит надо сделать pull. При подтягиваний изменений с сервера не слетит ли мой локальный
коммит и смогу ли я его потом запушить в удаленный репозиторий ?
    


Ответы

Ответ 1



Перед pull можно сделать коммит, или прописать команду git stash, чтобы все изменения сохранились временно в нём, при этом Ваш проект "откатывается" до версии сервера. При неправильном pull можно вызвать ненужный merge, если сделать коммит, при pull все коммиты с сервера просто соединяются с Вашим.

Ответ 2



Разобрался , ничего плохого не произойдет. В самом худшем случае, если свежие изменение затронули ваши файлы, то придется все смержить и запушить уже свои изменения.

среда, 29 января 2020 г.

SSL certificate problem при выполнении push на github

#git #github #git_push


При выполнении команды: 

git push -u origin master


Пишет:


  fatal: unable to access 'https:/github.com/..../....git': SSL certificate problem:
self signed certificate in certificate chain


Я понимаю, что он ругается на самоподписанный сертификат, да только ни в ~/.ssh ни
на гитхабе сртификатов у меня нет.

Git свежий. Кто что думает? Как исправить?
    


Ответы

Ответ 1



KIS 2015 в Firefox автоматически по умолчанию устанавливает свой сертификат и делает автоматическую проверку всех защищённых соединений. Для этого он подменяет сертификаты сайтов на свой сертификат в браузере! Чтобы убрать подмену сертификатов: В настройках KIS 2015: Настройка/Дополнительно/Сеть(параметры сети) - снять галочку с "Проверять защищённые соединения" и перезагрузить комп.

Ответ 2



Для игнорирования HTTPS-сертификатов в Git достаточно в файле конфигурации пользователя/системы/репозитория выставить параметр http.sslVerify в значение false: [http] sslVerify false Однако в случае с github-ом это не правильно - нужно искать причину того, почему они самоподписанные.

Ответ 3



если вы зарегистрированы на github-е и публичная часть вашего ключа добавлена в учётную запись, то можно соединяться с github-ом по протоколу ssh. ссылку на репозиторий можно получить на странице репозитория (см. справа: «You can clone with HTTPS, SSH, or Subversion») либо, уже имея http-ссылку, преобразовать её в ssh-ссылку, заменив https:// на git@ и первый слэш после адреса сайта — на двоеточие. пример: https://github.com/owncloud/android.git git@github.com:owncloud/android.git если репозиторий уже склонирован, и требуется лишь подправить ссылку, то это можно сделать примерно такой командой: $ git remote set-url origin <ссылка> посмотреть свои публичные ключи, закреплённые за учётной записью на github-е можно на соответствующей странице настроек.

Ответ 4



Как вариант, можно скачать CA с сайта curl: curl -k https://curl.haxx.se/ca/cacert.pem -o /path/to/cacert.pem А затем экспортировать путь к сертификату в переменные окружения: export GIT_SSL_CAINFO=/path/to/cacert.pem

Ответ 5



Только что была аналогичная проблема, два одинаковых компьютера. На одном работает, на другом нет. Сверил версии KIS, GIT, Tortoise Git. Обновил все до самых последних (18.0.0.405h, 2.17.0, 2.6.0.0) - заработало.

вторник, 28 января 2020 г.

Из локального репозитория создать удаленный репозиторий на github [дубликат]

#git #github #git_push


        
             
                
                    
                        
                            На этот вопрос уже даны ответы здесь:
                            
                        
                    
                
                        
                            Как создать репозиторий на GitHub через командную строку?
                                
                                    (3 ответа)
                                
                        
                                Закрыт 3 года назад.
            
                    
Вопрос в следующем, можно ли на github.com создать папку для репозитория git командами
с локального компьютера. Т.е. должны ли работать такие команды:

git remote add shot_link_name "https://github.com/user/myproject.git" 
git push -u shot_link_name master


Если github.com у пользователя user папка myproject.git отсутствует. 
Интересно знать нужно ли каждый раз заходить на сервер и сначала создавать удаленный
репозиторий и клонировать его или можно сначала делать все локально, а по необходимости
запушить все на сервер. Заранее спасибо всем ответившим.
    


Ответы

Ответ 1



Судя по выдаче гугла на запрос github create repository from local Можно воспользовать API гитХаба и послать запрос чрез него для создания репозитория как это описано на en-SO curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}' Замените USER на ваш юзерНэйм а REPO на имя нового репозитория. После отправки этого запроса вам надо будет ввести пароль от аккаунта и репозиторий будет создан. После чего можно добавить новый remote для локального репозитория и запушить всё что нужно: git remote add origin git@github.com:USER/REPO.git git push origin master

Ответ 2



Да, это можно сделать при помощи Github API. curl -u 'username:password' https://api.github.com/user/repos -d '{"name":"название_проекта","description":"Описание"}' git remote add origin https://github.com/username/название_проекта и т.д.

Ответ 3



Есть отличный CLI для GitHub, называется Hub. Не буду приводить всех инструкций по установке и настройке (они есть по ссылке), ограничусь примером. Следите за руками! hub create И это всё! Hub создаёт удалённый репозиторий GitHub для вашего пользователя, имеющий то же имя, что и корневая директория проекта; настраивает его как remote текущего репозитория; пушит содержимое. Разумеется, есть параметры, позволяющие задать другое имя, описание, создать приватный репозиторий и т.п. man hub (подразумевается alias git=hub): git create [NAME] [-p] [-d DESCRIPTION] [-h HOMEPAGE] Create a new public GitHub repository from the current git repository and add remote origin at "git@github.com:USER/REPOSITORY.git"; USER is your GitHub username and REPOSITORY is the current working directory name. To explicitly name the new repository, pass in NAME, optionally in ORGANIZATION/NAME form to create under an organization you're a member of. With -p, create a private repository, and with -d and -h set the repository's description and homepage URL, respectively.

Как правильно сплющить (объединить) удалённые коммиты?

#git #bitbucket #git_commit #git_push


Дано:

Последовательные коммиты А и В,  запушенные в удалённый репозиторий.

Задача:

Сделать из них один коммит С.

Вопрос:

Беглое гугленье убеждает меня в том, что достаточно что-то типа такого сделать:

git squash А
git squash В
git push origin branchname


Верно ли я понял и что в процессе может пойти не так?
    


Ответы

Ответ 1



Шаг 0: а можно ли это делать? что в процессе может пойти не так Если коммиты последовательные, то конфликтов изменений не будет. Но поскольку коммиты уже отправлены на удалённый репозиторий, то вам придётся переписывать историю там и что-нибудь может пойти не так у коллег. Вот пара вопросов о том, что и когда можно ребейзить и переписывать: В каких случаях rebase можно и нужно делать, а в каких нет? Откатить уже опубликованный коммит и опубликовать новый, не вызывая мержа у других Кратко: никогда нельзя это делать в стабильных ветках репозитория, где кроме вас есть ещё хоть один разработчик. Шаг 1а: сплющивание через rebase -i Под git squash вы наверное понимаете git rebase --interactive с последующим выбором опции squash. Действительно, можно сделать так: Ребейз к третьему коммиту с конца (пред-предпоследнему) git rebase -i HEAD^^ откроется такой документ: pick 7423f96 сообщение предпоследнего коммита pick 91e9b6e сообщение последнего коммита # Rebase c9e8f38..91e9b6e onto c9e8f38 (2 commands) ... Чтобы объединить два коммита в один нужно сделать squash последнего в предпоследний: pick 7423f96 сообщение предпоследнего коммита squash 91e9b6e сообщение последнего коммита А потом сохранить документ и выйти из редактора. Откроется новый документ, в котором можно написать сообщение для вновь полученного коммита. По умолчанию там будет: # This is a combination of 2 commits. # This is the 1st commit message: сообщение предпоследнего коммита # This is the commit message #2: сообщение последнего коммита Закомментированные строки не войдут в сообщение. Если оставить пустую строку, то rebase будет прерван. Шаг 1б: сплющивание через reset Поскольку нужно объединить N последних коммитов, отлично подойдёт более простой способ: # сначала очистим индекс (staging area, область подготовки коммита), # чтобы потом не закоммитить ничего лишнего git reset . # поехали git reset --soft HEAD^^ Произошло следующее: текущая ветка переставлена на коммит HEAD^^, т.е. на два коммита назад. изменения всех коммитов вплоть до, но не включая HEAD^^ собраны в индекс Можно сделать новый коммит: git commit -m'message' В отличие от способа с rebase, информация об авторе и дате оригинального коммита не сохраняется. Лучше не ребейзить таким образом чужие коммиты, т.к. информация об авторстве обычно важна. Шаг 1в: комбинированный подход Предположим, что в предпоследнем коммите у вас написано нормальное сообщение, раскрывающее суть изменений. А в последнем вы исправили опечатку. Т.е. было бы удобно объединить два коммита, оставив сообщение от предпоследнего. # То же, что и в шаге 1б: собираем содержимое последнего коммита в индекс git reset . git reset --soft HEAD^ # "редактируем" последний коммит, добавляя в него содержимое индекса # (на самом деле создаём новый коммит с тем же сообщением и переставляем на него ветку) git commit --amend --no-edit Шаг 2. запушить на удалённый репозиторий Поскольку вы переписали свою ветку, нужно будет запушить с -f. git push -f origin mybranch

Ответ 2



Я бы сделал так: git reset --soft HEAD~2 git commit git push -f origin Всё это, разумеется, если у Вас коммиты на конце текущей ветви. В противном случае придётся делать rebase.

Ответ 3



Нет такой команды как git squash, делайте через git rebase -i. $ git squash git: 'squash' is not a git command. See 'git --help'. Did you mean this? stash $ git --version git version 1.8.3.1 Вот тут ещё советуют создать алиас на squash. Проблем со сплющиванием двух последовательных коммитов не будет. :сли вам нужно влить B в A, то проблем не возникнет. (Так же как и при вливании N последовательных коммитов в предыдущий). Сложности могут возникнуть в том случае, если между A и B есть другие коммиты. В общем случае если нужно влить B в A - делайте так. (переключаемся на нужную ветку) $ git rebase -i HEAD~4 pick 8394e5a commit pick 33b90d9 A pick 5c633cf B pick 1604c23 yet another commit # Rebase 76e6ae0..1604c23 onto 76e6ae0 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out ~ "~/ansible/test/.git/rebase-merge/git-rebase-todo" 22L, 780C Приводите к виду: pick 8394e5a commit pick 33b90d9 A s 5c633cf B pick 1604c23 yet another commit Далее выходите с сохранением и пушим изменения в удалённую ветку. Как обычно: не забываем, что изменение истории через rebase требует git push -f, что в общем случае не приветствуется в командной работе.

воскресенье, 12 января 2020 г.

Как работать со своей отдельной веткой в репозитории?

#git #git_push #git_pull


До этого дня работал в отдельном репозитории и сегодня поступила команда, что для
меня открыт branch от общего проекта, и мне надо туда перейти и мержить.

Я создал у себя новый branch, перешел туда и сделал pull от общего проекта, и тут
у меня смешались файлы.

Как вообще в таком случае поступать надо? Клонировать весь проект и работать с теми
файлами, которые тебе предназначены, или как только свою ветку клонировать или pull-ить? 

И потом еще как push-ить именно в свою ветку?
    


Ответы

Ответ 1



предположим, что до этого вы работали с веткой master. и вас известили, что в основном репозитории для вас создали ветку test. получите все обновления из основного репозитория: $ git fetch после этого вы увидите ветку test из основного репозитория (вывод команды — ориентировочный): $ git branch -r origin/HEAD -> origin/master origin/master origin/test создайте в своём локальном репозитории ветку (например, test), сразу же «привязав» её к ветке test из основного репозитория: $ git checkout -b test origin/test Branch test set up to track remote branch test from origin. Switched to a new branch 'test' теперь вы можете вносить изменения, коммитить их, отправлять в основной репозиторий командой: $ git push и получать обновления из этой ветки основного репозитория командой: $ git pull и «мёрджить» коммиты из другой ветки: $ git merge другая-ветка в любой момент (ну, почти в любой) вы можете переключить свою рабочую копию файлов на другую ветку: $ git checkout другая-ветка и «вернуться обратно»: $ git checkout test

пятница, 10 января 2020 г.

Работа с Github и Bitbucket с одного компьютера

#git #github #веб_программирование #bitbucket #git_push


Имеется ноутбук с установленным git 2.9.3. Есть аккаунт на Github и Bitbucket, зарегистрированный
на один и тот же e-mail. 


Могу ли я заливать одни проекты на Github, а другие Bitbucket?
И нужны ли дополнительные настройки при заливке на Bitbucket?

    


Ответы

Ответ 1



"Заливка" (Отправление файлов и изменений из локального репозитория в удалённый) осуществляется по адресу, который указан в remote каждого локального репозитория. Когда вы клонируете репозиторий с удалённого сервера (Github или Bitbucket) то в репозиторий устанавливается remote с именем origin в котором указан этот адрес. При git push origin файлы/изменения отправятся на удалённый репозиторий с указанным адресом. При этом ничто не ограничивает вас в смене и добавлении других remote-ов. Т.е. вы можете склонировать репу с Github, поменять remote и пушить на Bitbucket. Или наоборот. А можете добавить ещё один remote для к-л репы и пушить и в Github и в Bitbucket.

четверг, 2 января 2020 г.

В чем разница git push -u origin master и git push?

#git #github #git_push


Ну вот собственно, такой простой вопрос... Создал ветку, внес изменения, добавил
файлы в отслеживаемые, закомитил, смержил с веткой master и вот теперь хочу отправить
изменения на сервер...

Как это сделать просто 

git push


или 

git push -u origin master


?
    


Ответы

Ответ 1



Второй вариант явно показывает, куда вы пушите коммит, первый - неявно. В большинстве случаев достаточно указать первый вариант, в крайнем случае вам появится (git 2.0 - 2.8) нотификация типа: [ak@server abc]$ git push warning: push.default is unset; its implicit value is changing in Git 2.0 from 'matching' to 'simple'. To squelch this message and maintain the current behavior after the default changes, use: git config --global push.default matching To squelch this message and adopt the new behavior now, use: git config --global push.default simple See 'git help config' and search for 'push.default' for further information. (the 'simple' mode was introduced in Git 1.7.11. Use the similar mode 'current' instead of 'simple' if you sometimes use older versions of Git) Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 367 bytes | 0 bytes/s, done. Total 3 (delta 2), reused 0 (delta 0) To abc@asdf:/asdfasddf.git b41acb4..b8c32bd master -> master Цитирую: Одним из самых главных изменений является поведение команды git push. Теперь по умолчанию (если не указана ветка) push будет осуществлен только в текущую ветку. Git 1.* по умолчанию делал push во все ветки, которые были изменены локально. Конечно же можно вернуться к прежнему поведению, для этого служит опция push.default. Это очень популярный вопрос на английском so, там тоже самое написано: matching означает, что git push отправит все ваши локальные ветки в такие же на удалённом сервере. simple означает, что git push отправит только текущую ветку в такую же на удалённом сервере. Simple более интуитивный режим, поэтому он является режимом по умолчанию и используется если push.default не установлен.

среда, 25 декабря 2019 г.

Git не подхватывает config любого уровня. Или “Поле user.name бесполезно?”

#linux #git #git_push #git_config


Привет всем!

Такая проблема: Git почему-то не подхватывает настройки, когда я пытаюсь запушить
что-либо. То есть он постоянно просит ввести Username и Password, хотя, по идее, он
должен просить только Password

Настройки делал глобальные. То есть:

git config --global user.name 'SomeName'
git config --global user.email some@email.com


Но также пытался создать и локальный конфиг, и системный конфиг... Ни один не подхватывается.

Пытаюсь подключиться к GitHub, использую Linux.

Читал конфиги, думал, может что-то не так пишется, но нет. Всё в конфигах прописано
корректно. Смущает разве что только табуляция вместо пробелов. Но не я устанавливаю
правила форматирования.

Интересно то, что с GitLab всё отлично работает. Ну у них работает всё, ибо они сразу
дают твой логин в url, а вот с GitHub это решается заменой origin с

https://github.com/username/repo.git


на

https://username@github.com/username/repo.git


Но я не пойму, для чего тогда нужны настройки, если они не подхватываются? Может,
они работают как-то иначе/предназначены для чего-то другого?
    


Ответы

Ответ 1



Смысл user.name и user.email Настройки user.name и user.email используются для того, чтобы сохранять в коммитах информацию об авторстве. Например, так можно посмотреть данные последнего коммита: git cat-file commit HEAD Пример вывода, обратите внимание на третью и четвертую строки: tree 2159e904426c047e790d559c7cc62dd3d4b5174e parent 60b9a77a21a464d71171e483d1bc834ea6fde209 author Name Surname 1461622007 +0200 committer Name Surname 1461622007 +0200 Смысл такой: author – автор изменений в коде committer – тот, кто закоммитил эти изменения в git. Обычно они совпадают, в редких случаях отличаются. Что делать с авторизацией Способ авторизации зависит от того, что вы используете для обмена данных с удаленным репозиторием: Протокол HTTPS (с адресом вида https://github.com/username/repo-name.git) Протокол SSH (с адресом вида git@github.com:username/repo-name.git) Собственный протокол Git. Используется редко, здесь рассматривать не будем. (Подробнее о протоколах) В первом случае вам всегда нужно вводить логин и пароль. Вот vp_arth подсказывает в комментарии, что можно настроить их кеширование, чтобы вводить приходилось пореже: git config credential.helper 'cache --timeout=300' Вместо этого рекомендую вам использовать протокол SSH, где для авторизации используются ключи и поэтому не нужно каждый раз вводить логин и пароль. Авторизацию по SSH нужно однократно настроить.

четверг, 19 декабря 2019 г.

Git не могу сделать push

#git #github #git_push


При попытке сделать пуш на гитхаб получаю ошибку:

Push failed
Failed with error: fatal: Could not read from remote repository.

Все было нормально, а тут на новом проекте такое.. Как можно решить эту проблему?
    


Ответы

Ответ 1



После действий описанных в https://habrahabr.ru/post/266667/ всё заработало. Опишу здесь, что сделал: В папке с папкой git открыть GIT GUI Here; Help-> Показать SSH -> если всё пусто, то жмём сгенерировать SSH; Вставляем его в настройках Github; Пробуем git push; Если пользуетесь Intellij IDEA, то в настройках git (Ctrl+Alt+S->Version Control->git) выберете Built-in. При push будет запрашиваться пароль, который вы ввели при генерации SSH.

Ответ 2



Ошибка "Could not read from remote repository" означает что git не может прочитать из внешнего репозитория. Тут два варианта: Внешний репозиторий по какой-то причине не работает или не доступен (проблемы на сервере, проблемы с сетью и т.п.) Адрес репозитория по умолчанию не корректен. Можно проверить с помощью команды git remote -v.

Ответ 3



Если команда git remote -v работает корректно то можно открыть GIT GUI Here для данного локального репозитория и если там не пустой SSH, то просто жмем кнопку push и у меня все сработало, хотя Intellij Idea выдовало такуюже ошибку. При этом до этого все изменения должны быть закомичены, а команда git status должна показывать что в локальном все число: nothing to commit, working tree clean.

Ответ 4



может кому то поможет, я решил вопрос таким образом если после git config -l показывает remote.origin.url=git@github.com:login/репозиторий нужно изменить адрес таким способом git config remote.origin.url https://github.com/_login_/репозиторий после этого git push -u -f origin master и у меня всё заработало

пятница, 13 декабря 2019 г.

Отправить изменения в несколько репозиториев одной командой push

#git #git_push #git_remote


В своём локальном репозитории можно подключить несколько удалённых репозиториев (git
remote add ...) и отправлять в них изменения командой git push имя-репозитория имя-ветки
— по одной команде на каждый репозиторий.

А как это сделать одной командой git что-то-там? без написания скрипта или функции
или псевдонима (alias-а).
    


Ответы

Ответ 1



для каждого удалённого репозитория можно задать pushurl, т.е., url, по которому будут отправляться изменения по команде push. этот pushurl, кстати, может и не совпадать с url данного репозитория. вот такой фокус: делаете push, вроде бы, в репозиторий на bitbucket-е, а изменения идут на github. более того: таких pushurl-ов может быть больше одного. и изменения одной командой отправятся сразу по нескольким url-ам. добавляется pushurl с помощью команды примерно такого содержания: $ git remote set-url --add --push имя-репозитория url-репозитория от теории к практике. создадим три (чтоб наверняка) bare-репозитория: $ for i in 1 2 3; do git init --bare repo$i; done Initialized empty Git repository in ./repo1/ Initialized empty Git repository in ./repo2/ Initialized empty Git repository in ./repo3/ и сделаем клон первого из них: $ git clone repo1 work Cloning into 'work'... warning: You appear to have cloned an empty repository. done. $ cd work посмотрим умолчальную конфигурацию remote-ов: $ git config --get-regexp "^remote" remote.origin.url ../repo1 remote.origin.fetch +refs/heads/*:refs/remotes/origin/* а теперь добавим pushurl-ы для всех созданных bare-репозиториев, не забыв и про сам исходный репозиторий (../repo1): $ for i in 1 2 3; do git remote set-url --add --push origin ../repo$i; done $ git config --get-regexp "^remote" remote.origin.url ../repo1 remote.origin.fetch +refs/heads/*:refs/remotes/origin/* remote.origin.pushurl ../repo1 remote.origin.pushurl ../repo2 remote.origin.pushurl ../repo3 как видно, pushurl-ы благополучно добавились. создаём коммит и отправляем его командой push: $ date > file $ git add file $ git commit -m 1 [master (root-commit) 2d68407] 1 1 file changed, 1 insertion(+) create mode 100644 file $ git push Counting objects: 3, done. Writing objects: 100% (3/3), 228 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ../repo1 * [new branch] master -> master Counting objects: 3, done. Writing objects: 100% (3/3), 228 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ../repo2 * [new branch] master -> master Counting objects: 3, done. Writing objects: 100% (3/3), 228 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ../repo3 * [new branch] master -> master вуаля! коммит отправился во все три bare-репозитория одной командой! а как насчёт других веток? создадим ещё одну ветку (new), добавим в неё коммит и отправим изменения: $ git checkout -b new Switched to a new branch 'new' $ date >> file $ git commit -am 2 [new c82bfe5] 2 1 file changed, 1 insertion(+) $ git push -u origin new Counting objects: 3, done. Writing objects: 100% (3/3), 264 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ../repo1 * [new branch] new -> new Branch new set up to track remote branch new from origin. Counting objects: 3, done. Writing objects: 100% (3/3), 264 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ../repo2 * [new branch] new -> new Branch new set up to track remote branch new from origin. Counting objects: 3, done. Writing objects: 100% (3/3), 264 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ../repo3 * [new branch] new -> new Branch new set up to track remote branch new from origin. эта «магия» работает и с новыми ветками! коммит отправился в ветки new во всех трёх bare-репозиториях. ответ основан на информации из этого и этого ответов.

Ответ 2



Если вкратце. // Добавляем git remote add "all" git@github.com:fudeglan/gigalab.uz.git git remote set-url --add --push "all" git@github.com:fudeglan/gigalab.uz.git git remote set-url --add --push "all" git@bitbucket.org:fudeglan/gigalab.uz.git git remote set-url --add --push "all" git@gitlab.com:fudeglan/gigalab.uz.git // Отправляем git push all .git/config примерно будет таким [remote "all"] url = git@github.com:fudeglan/gigalab.uz.git fetch = +refs/heads/*:refs/remotes/all/* pushurl = git@github.com:fudeglan/gigalab.uz.git pushurl = git@bitbucket.org:fudeglan/gigalab.uz.git pushurl = git@gitlab.com:fudeglan/gigalab.uz.git

Как обнулить историю Git?

#git #git_commit #git_remote #git_push


Ситуация такая: на сервере удалил репозиторий и создал заново, с локального теперь
нужно сделать push, но если сделаю, то всю историю коммитов запишет на сервер.

Как начать с нуля?
    


Ответы

Ответ 1



Все эти инструкции верны, если на удаленном сервере у вас пусто, а локально - есть проект и репозиторий Git с историей, которую вы хотите удалить. Что будет потеряно безвозвратно Собственно, история. Вы точно хотите ее потерять? Ради нее весь Git и придумывался. Весь код в не-слитых (unmerged) ветках. Весь код в orphaned ветках. Метки (tags) Быстрый способ Найдите первый коммит в ветке, запомните его sha1. git log --oneline Переключитесь на тот коммит, который хотите сохранить в итоге. git checkout master Теперь используем git reset --soft чтобы сделать из всей истории один коммит (подробнее - пункт 4.1: Как вернуться (откатиться) к более раннему коммиту? ). git reset --soft git commit -m'слил историю в один коммит' Долгий способ Сделайте бэкап локального репозитория. Можно запушить на резервный удаленный репозиторий, а можно просто взять и переместить папку .git в другое место. mkdir ../git-backup mv .git ../git-backup/.git Если не переместили локально, а забэкапили куда-то еще: удаляем папку. rm -Rf .git Теперь заново инициализируем репозиторий: git init Добавляем все файлы в рабочей области и делаем коммит. git add . git commit -m'начал с нуля' Когда все готово Подключаем удаленный репозиторий и заливаем на него изменения: git remote add origin git push -u origin --all

Ответ 2



Сделать clone, скопировать файлы (без .git), сделать push! Нет? ))

Ответ 3



Эта команда делает совсем другое: стирает всю историю до commitId и возвращает рабочую область к его состоянию. При этом вы потеряете данные более поздних коммитов. git reset --hard commitId #УДАЛЯЕТ ИСТОРИЮ GIT