<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev-hyewon.log</title>
        <link>https://velog.io/</link>
        <description>일이 재밌게 돌아가는 군!</description>
        <lastBuildDate>Tue, 27 May 2025 07:52:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev-hyewon.log</title>
            <url>https://velog.velcdn.com/images/dev-hyewon/profile/14cd56b8-b46e-4a68-8912-d6b62cc3e206/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev-hyewon.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev-hyewon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[ Rocky linux에 Jenkins 설치하기 #1]]></title>
            <link>https://velog.io/@dev-hyewon/Rocky-linux%EC%97%90-Jenkins-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0-1</link>
            <guid>https://velog.io/@dev-hyewon/Rocky-linux%EC%97%90-Jenkins-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0-1</guid>
            <pubDate>Tue, 27 May 2025 07:52:17 GMT</pubDate>
            <description><![CDATA[<h2 id="😘-핵심-command">😘 핵심 Command</h2>
<pre><code class="language-bash">[rockylinux@rocky9 ~]$ sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
[rockylinux@rocky9 ~]$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
[rockylinux@rocky9 ~]$ sudo systemctl start jenkins
[rockylinux@rocky9 ~]$ sudo systemctl enable jenkins
[rockylinux@rocky9 ~]$ sudo systemctl status jenkins</code></pre>
<br/>


<h2 id="😵-오류-상황-기록">😵 오류 상황 기록</h2>
<h3 id="①-jenkins-실행-시-오류가-발생함">① jenkins 실행 시 오류가 발생함</h3>
<p><code>sudo systemctl start jenkins</code>를 실행했더니 아래와 같은 Fail 문구가 출력되었습니다.</p>
<div style="color:red">
  Job for jenkins.service failed because the control process exited with error code.<br/>
  See "systemctl status jenkins.service" and "journalctl -xeu jenkins.service" for details.
</div>
<br/>

<h3 id="②-오류-원인-파악하기">② 오류 원인 파악하기</h3>
<p><code>journalctl -u jenkins.service</code> 명령어를 실행해 무엇이 문제인지 확인합니다.</p>
<div>
  May 27 00:20:22 rocky9 systemd[1]: Starting Jenkins Continuous Integration Server...<br/>
  May 27 00:20:22 rocky9 jenkins[16025]: jenkins: failed to find a valid Java installation<br/>
  May 27 00:20:22 rocky9 systemd[1]: <strong>jenkins.service: Main process exited, code=exited, status=1/FAILURE</strong><br/>
  May 27 00:20:22 rocky9 systemd[1]: <span style="color:lightgreen">jenkins.service: Failed with result 'exit-code'.</span><br/>
  May 27 00:20:22 rocky9 systemd[1]: <span style="color:red">Failed to start Jenkins Continuous Integration Server.</span><br/>
  May 27 00:20:22 rocky9 systemd[1]: jenkins.service: Scheduled restart job, restart counter is at 1.<br/>
  May 27 00:20:22 rocky9 systemd[1]: Stopped Jenkins Continuous Integration Server.<br/>
</div>
<br/>

<p>이런, JAVA 설치를 깜빡했네요. <em>(어휴 바보 멍충이)</em>
이전에 설치했던 기록에 따라 Java11버전으로 설치해야겠습니다.</p>
<h3 id="③-java-설치하기">③ Java 설치하기</h3>
<p>jenkins를 설치하기 위해<code>sudo dnf install java-11-openjdk -y</code> 를 명령하고 제대로 설치되었는지 확인합니다.</p>
<pre><code class="language-bash">[rockylinux@rocky9 ~]$ java -version
openjdk version &quot;11.0.25&quot; 2024-10-15 LTS
OpenJDK Runtime Environment (Red_Hat-11.0.25.0.9-1) (build 11.0.25+9-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-11.0.25.0.9-1) (build 11.0.25+9-LTS, mixed mode, sharing)</code></pre>
<p>이제 다시 jenkins를 실행하기 위해 <code>sudo systemctl start jenkins</code> 명령합니다.
그리고 또 다시 보이는 Fail...
<br/></p>
<p>이번엔 뭐가 문제인지 <code>journalctl -u jenkins.service</code> 으로 다시 확인합니다.</p>
<div>
  May 27 00:28:51 rocky9 systemd[1]: Starting Jenkins Continuous Integration Server...<br/>
  May 27 00:28:52 rocky9 jenkins[1815]: Running with Java 11 from /usr/lib/jvm/java-11-openjdk-11.0.25.0.9-7.el9.x86_64, which is older than the minimum required version (Java 17).<br/>
  May 27 00:28:52 rocky9 jenkins[1815]: Supported Java versions are: [17, 21]
  May 27 00:28:52 rocky9 jenkins[1815]: See https://jenkins.io/redirect/java-support/ for more information.<br/>
  May 27 00:28:52 rocky9 systemd[1]: <strong>jenkins.service: Main process exited, code=exited, status=1/FAILURE</strong><br/>
  May 27 00:28:52 rocky9 systemd[1]: <span style="color:lightgreen">jenkins.service: Failed with result 'exit-code'.</span><br/>
  May 27 00:28:52 rocky9 systemd[1]: <span style="color:red">Failed to start Jenkins Continuous Integration Server.</span><br/>
  May 27 00:28:52 rocky9 systemd[1]: jenkins.service: Scheduled restart job, restart counter is at 1.<br/>
  May 27 00:28:52 rocky9 systemd[1]: Stopped Jenkins Continuous Integration Server.
</div>
<br/>

<p>아하 이번엔 버전이 문제라고 합니다. <em>(어휴 바보 멍충이2)</em>
작년엔 11 버전으로 실행되었는데, 그새 버전이 틀어졌나봅니다.
현재 설치된 Java 버전(OpenJDK 11.0.25)은 Jenkins의 최소 요구사항인 Java 17에 미치지 못한답니다.</p>
<h3 id="④-jenkins-요구사항에-맞춰-java17-설치하기">④ jenkins 요구사항에 맞춰 Java17 설치하기</h3>
<p>java 17 버전을 설치하기 위해 <code>sudo dnf install java-17-openjdk -y</code>를 명령한 뒤
제대로 설치되었는지 확인합니다.</p>
<pre><code class="language-bash">[rockylinux@rocky9 ~]$ java -version
openjdk version &quot;17.0.15&quot; 2025-04-15 LTS
OpenJDK Runtime Environment (Red_Hat-17.0.15.0.6-1) (build 17.0.15+6-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-17.0.15.0.6-1) (build 17.0.15+6-LTS, mixed mode, sharing)</code></pre>
<h3 id="⑤-문제-해결">⑤ 문제 해결!</h3>
<p>이후 jenkins를 실행 시 정상적으로 동작하는 것을 확인했습니다.
만약 기존에 설치했던 버전으로 표시된다면 <code>alternatives</code>으로 설치된 java 중에서 원하는 버전을 선택할 수 있습니다.</p>
<br/>

<h2 id="🥹-정상-동작-확인">🥹 정상 동작 확인</h2>
<pre><code class="language-bash">[rockylinux@rocky9 ~]$ sudo systemctl start jenkins
[rockylinux@rocky9 ~]$ sudo systemctl enable jenkins
Created symlink /etc/systemd/system/multi-user.target.wants/jenkins.service → /usr/lib/systemd/system/jenkins.service.
[rockylinux@rocky9 ~]$ sudo systemctl status jenkins
● jenkins.service - Jenkins Continuous Integration Server
     Loaded: loaded (/usr/lib/systemd/system/jenkins.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-05-27 00:41:17 EDT; 17s ago
   Main PID: 1813 (java)
      Tasks: 53 (limit: 48714)
     Memory: 1.0G
        CPU: 14.735s
     CGroup: /system.slice/jenkins.service
             └─1813 /usr/lib/jvm/java-17-openjdk-17.0.15.0.6-2.el9.x86_64/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8080</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 절대 경로 설정
(react-app-rewired, customize-cra)]]></title>
            <link>https://velog.io/@dev-hyewon/React-%EC%A0%88%EB%8C%80-%EA%B2%BD%EB%A1%9C-%EC%84%A4%EC%A0%95react-app-rewired-customize-cra</link>
            <guid>https://velog.io/@dev-hyewon/React-%EC%A0%88%EB%8C%80-%EA%B2%BD%EB%A1%9C-%EC%84%A4%EC%A0%95react-app-rewired-customize-cra</guid>
            <pubDate>Sun, 13 Aug 2023 13:51:27 GMT</pubDate>
            <description><![CDATA[<p>CRA(Create-React-App)로 React 프로젝트를 생성하면 기본적으로 상대 경로를 사용하는데,
폴더가 많아지면서 불편해지게 되었습니다.
모든 파일에서 동일한 경로를 사용해서 개발 효율을 높이기 위해서 수정하게 되었습니다.</p>
<p>목표는 아래와 같이 상대 경로로 표시 되는 것을 절대 경로로 처리하는 겁니다.</p>
<pre><code class="language-js">import Layout from &quot;./componenet/layout/layout&quot;;
import Main from &quot;./page/main&quot;;
import { PATH } from &quot;./utils/constant&quot;;</code></pre>
<p>그런데 아래처럼 완전히 절대 경로도 설정해 보았더니,
eslint의 import/order 정렬 설정에 의해 internal로 그룹화되었습니다.</p>
<pre><code class="language-js">import Layout from &#39;components/layout/layout&#39;;
import Main from &#39;pages/main&#39;;
import { PATH } from &#39;utils/constant&#39;;</code></pre>
<p>src 내 파일들을 pathGroup으로 만들기 위해 @로 시작되도록 매핑하고자 합니다.</p>
<pre><code class="language-js">import Layout from &#39;@layout/layout&#39;;
import Main from &#39;@pages/main&#39;;
import { PATH } from &#39;@utils/constant&#39;;</code></pre>
<h1 id="📌-모듈-경로-설정">📌 모듈 경로 설정</h1>
<h3 id="1-jsconfigjson-파일-생성구성하기">1. jsconfig.json 파일 생성/구성하기</h3>
<p>Root Directory에 <em>jsconfig.json</em> 파일을 생성합니다.
만약 타입스크립트를 사용하고 있다면 <em>tsconfig.json</em> 파일을 생성하면 됩니다.
exclude나 include를 사용해서 프로젝트에 포함할 파일을 지정합니다.
baseUrl은 기본 디렉토리를 지정합니다.
저는 절대 경로를 src부터 쓰고 싶다면 baseUrl에 <code>.</code>을 입력하고,
src 하위 디렉토리부터 쓰고 싶다면 baseUrl에 <code>src</code>를 입력하세요.
paths에는 경로 매핑을 지정합니다.
(제 경우 eslint 설정을 위해 @를 붙여서 매핑했는데, @ 없이 매핑해도 괜찮아요.)</p>
<pre><code class="language-json">{
  &quot;compilerOptions&quot;: {
      &quot;baseUrl&quot;: &quot;src&quot;,
      &quot;paths&quot;: {
        &quot;@cloud/*&quot;: [&quot;cloud/*&quot;],
        &quot;@common/*&quot;: [&quot;components/common/*&quot;],
        &quot;@layout/*&quot;: [&quot;components/layout/*&quot;],
        &quot;@hooks/*&quot;: [&quot;hooks/*&quot;],
        &quot;@pages/*&quot;: [&quot;pages/*&quot;],
        &quot;@utils/*&quot;: [&quot;utils/*&quot;]
      }
  },
  &quot;include&quot;: [
      &quot;src&quot;
  ]
}</code></pre>
<p>jsconfig.json에 대한 자세한 내용은 이 <a href="https://code.visualstudio.com/docs/languages/jsconfig">링크</a>를 참고 바랍니다.</p>
<h3 id="2-에디터-재시작하기">2. 에디터 재시작하기</h3>
<p><em>jsconfig.json</em>의 내용이 바로 적용되지 않을 수 있습니다.
제 경우 VSCode를 종료시켰다가 다시 열어주니 잘 동작했습니다.
<del>아마 에디터를 열었을 때 캐시를 업데이트하는 게 아닐까합니다. (제 생각에!)</del></p>
<h3 id="3-모듈-경로-설정-완료">3. 모듈 경로 설정 완료</h3>
<p>ctrl을 누른 상태로 경로에 마우스를 대면 연결된 모듈의 경로가 자동 완성되어 표시됩니다.
<img src="https://velog.velcdn.com/images/dev-hyewon/post/62a6a384-98a3-44a0-b909-2f23b2a8e404/image.png" alt="">
<em>jsconfig.json</em> 파일이 없을 때는 절대 경로에 대해 모듈이 표시되지 않았는데,
지금은 올바른 모듈 경로를 인식하는 것을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/dev-hyewon/post/e4a584e2-a734-494d-a9a4-eeaded734f20/image.png" alt=""></p>
<h3 id="4-컴파일-시-오류-발생">4. 컴파일 시 오류 발생</h3>
<p><em>jsconfig.json</em>만 설정한 상태에서는 실행(<code>npm start</code>)했을 때 아래와 같이 컴파일 오류가 발생합니다.</p>
<pre><code class="language-bash">Failed to compile.

Module not found: Error: Can&#39;t resolve &#39;@layout/layout&#39; in &#39;C:\workspace\portfolio\src&#39;
</code></pre>
<p>CRA(create-react-app) 프로젝트는 빌드할 때 내부적으로 webpack을 이용합니다.
VSCode같은 에디터는 <em>jsconfig.json</em>를 통해 경로를 인식하고 경로 자동 완성을 통해 코드 작성을 도와주지만 webpack은 <em>jsconfig.json</em>에서 설정한 경로를 인식하지 못합니다.
따라서 webpack의 모듈 해석을 변경하기 위한 별도의 설정이 필요합니다.</p>
<h1 id="📌-webpack-설정을-오버라이딩-하자">📌 webpack 설정을 오버라이딩 하자</h1>
<h2 id="eject를-하지-않을-것이다">eject를 하지 않을 것이다.</h2>
<p><span style="color:red"><em>주의: 빨간색 명령어 입력하지 마세요. 이전 상태로 돌아갈 수 없어요.</em></span>
CRA(create-react-app)로 프로젝트를 생성했을 때는 간결한 디렉토리를 위해 여러 설정이 숨겨져 있는데, webpack에 대한 설정을 건드리려면 터미널에서 <span style="color:red"><code>npm run eject</code></span>를 입력해서 이 숨겨진 폴더 config를 끄집어내서 웹팩 설정 파일인 <em>webpack.config.js</em>를 수정해야 합니다.</p>
<p>그런데 문제는 <span style="color:red"><code>npm run eject</code></span>를 실행하면 숨겨진 모든 설정이 밖으로 추출됩니다. config 폴더 뿐만 아니라 scripts 폴더, <em>package.json</em> 파일 내에서도 그동안 안보였던 dependency나 babel, jest 설정 등 모든 게 드러납니다. eject한 순간부터 CRA가 자동으로 처리해주던 babel과 webpack 설정을 직접 유지 보수해야합니다. (자세한 내용은 이 <a href="https://github.com/facebook/create-react-app#whats-included">링크</a>에서 확인 바랍니다.)</p>
<p>아직 CRA로부터 독립하기엔 갈길이 멀기 때문에 왠만하면 eject는 하지 않고자 합니다.
babel도 잘 모르고, 의존성을 매번 체크하자니 간단한 프로젝트를 만들려다가 일이 커질 것 같습니다.
그리고 무시무시한 점은 <strong>한번 eject하면 원래 상태로 돌아갈 수 없습니다.</strong> &quot;Are you sure you want to eject? this action is permenent&quot;라는 경고 문구가 아주 무섭습니다.</p>
<h1 id="📌-webpack-모듈-해석-변경">📌 webpack 모듈 해석 변경</h1>
<p>그러나 다행인 부분은 eject하지 않아도 CRA의 설정을 오버라이딩하는 라이브러리가 있다는 점입니다. 대표적으로 &#39;craco(Create React App Configuration Override)&#39;와 &#39;react-app-rewired&#39;가 있습니다.</p>
<p>그런데 &#39;craco&#39;는 CRA5를 지원하지 않는다는 말이 있더라구요?
<a href="https://craco.js.org/docs/getting-started/">craco.js.org</a>를 보니craco 7.0.0은 지원한다고 명시되어 있는데, 최근에 업데이트된 모양이에요.</p>
<p>&#39;craco&#39;가 업데이트도 더 자주하고 확장성이 있는 모양이지만 거기까진 바라지 않고,
이 프로젝트에서는 단순히 모듈 해석만 변경하고 싶기 때문에
CRA의 기본 스크립트를 간단하게 대체하는 방식으로 동작하는 &#39;react-app-rewired&#39;로 진행하겠습니다.</p>
<h3 id="1-react-app-rewired-라이브러리-설치하기">1. react-app-rewired 라이브러리 설치하기</h3>
<p><code>npm i -D react-app-rewired</code> 명령어로 devDependencies에 react-app-rewired 라이브러리를 추가해주세요.</p>
<h3 id="2-packagejson-파일-수정하기">2. package.json 파일 수정하기</h3>
<p>Root Directory에 있는 package.json 파일을 수정합니다.
아래처럼 package 파일의 scripts 부분의 명령어를 <em>react-scripts</em> 에서 <em>react-app-rewired*로 변경하세요. (eject는 수정하지 않아도 됩니다.)
아래와 같이 script를 수정하고 실행(<code>npm start</code>) 시 CRA의 webpack 설정을 오버라이딩 하기 위해 *config-overrides.js</em> 파일을 실행하게 되는데, 아직 <em>config-overrides.js</em> 파일이 없으니 파일을 생성하고 webpack 설정을 하면 됩니다.</p>
<pre><code class="language-json">{
  //...
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;react-app-rewired start&quot;,
    &quot;build&quot;: &quot;react-app-rewired build&quot;,
    &quot;test&quot;: &quot;react-app-rewired test&quot;,
    &quot;eject&quot;: &quot;react-scripts eject&quot;
  },
  //...

}</code></pre>
<h3 id="3-config-overridesjs-파일-생성하기">3. config-overrides.js 파일 생성하기</h3>
<p>Root Directory에 <em>config-overrides.js</em> 파일 생성합니다.
<em>jsconfig.json</em>의 compilerOptions에 paths까지 설정하지 않았다면 아래와 같은 구성으로 마무리해도 될 것 같습니다.</p>
<pre><code class="language-js">
module.exports = function override(config, env) {
  //기존의 모듈 경로 설정을 절대 경로로 수정합니다.
  config.resolve.modules.push(path.resolve(&#39;./src&#39;));
  return config;
}</code></pre>
<p>(자세한 내용은 이 <a href="https://www.npmjs.com/package/react-app-rewired">링크</a>를 참고하시기 바랍니다.)</p>
<h1 id="📌-webpack-모듈-경로-매핑">📌 webpack 모듈 경로 매핑</h1>
<p>모듈 경로를 매핑시키기 위해 CRA의 웹팩 설정을 조정하고 커스터마이즈하는 데에 특화된 라이브러리인 customize-cra를 추가로 설치하겠습니다.</p>
<h3 id="1-customize-cra-라이브러리-설치하기">1. customize-cra 라이브러리 설치하기</h3>
<p><code>npm i -D customize-cra</code> 명령어로 devDependencies에 &#39;customize-cra&#39; 라이브러리를 추가해주세요.</p>
<h3 id="2-config-overridesjs-파일-수정하기">2. config-overrides.js 파일 수정하기</h3>
<p>아까의 임의로 만든 함수 override를 지우고 &#39;customize-cra&#39;의 override, addWebpackAlias를 사용해서 모듈 경로를 매핑하도록 하겠습니다.
<em>jsconfig.json</em>의 compilerOptions에 paths의 key값을 그대로 가져오고 path모듈에 __dirname를 함께 사용한 절대 경로를 만들어서 value로 사용합니다.</p>
<pre><code class="language-js">const { override, addWebpackAlias } = require(&#39;customize-cra&#39;);
const path = require(&#39;path&#39;);

module.exports = override(
  addWebpackAlias({
    &#39;@cloud&#39;: path.resolve(__dirname, &#39;src&#39;, &#39;cloud&#39;),
    &#39;@common&#39;: path.resolve(__dirname, &#39;src&#39;, &#39;components&#39;, &#39;common&#39;),
    &#39;@layout&#39;: path.resolve(__dirname, &#39;src&#39;, &#39;components&#39;, &#39;layout&#39;),
    &#39;@hooks&#39;: path.resolve(__dirname, &#39;src&#39;, &#39;hooks&#39;),
    &#39;@pages&#39;: path.resolve(__dirname, &#39;src&#39;, &#39;pages&#39;),
    &#39;@utils&#39;: path.resolve(__dirname, &#39;src&#39;, &#39;utils&#39;),
  })
);</code></pre>
<h1 id="경로-설정-완료">경로 설정 완료!</h1>
<p>이제 webpack이 매핑된 모듈 경로를 인식할 수 있게 되었습니다.
실행(<code>npm start</code>)과 빌드(<code>npm run build</code>)가 잘되는 지 테스트해보세요.
절대 경로를 매핑하고 난 뒤 가장 좋은 점은 경로를 짧게 유지할 수 있다는 것과 모든 파일에서 같은 경로가 사용된 다는 거죠. 다른 파일에서 경로 복사해서 붙여넣으면 금방이에요.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ESLint] indent 규칙에 의해 SwitchCase 들여쓰기 이슈 발생]]></title>
            <link>https://velog.io/@dev-hyewon/ESLint-indent-%EA%B7%9C%EC%B9%99%EC%97%90-%EC%9D%98%ED%95%B4-SwitchCase-%EB%93%A4%EC%97%AC%EC%93%B0%EA%B8%B0-%EC%9D%B4%EC%8A%88-%EB%B0%9C%EC%83%9D</link>
            <guid>https://velog.io/@dev-hyewon/ESLint-indent-%EA%B7%9C%EC%B9%99%EC%97%90-%EC%9D%98%ED%95%B4-SwitchCase-%EB%93%A4%EC%97%AC%EC%93%B0%EA%B8%B0-%EC%9D%B4%EC%8A%88-%EB%B0%9C%EC%83%9D</guid>
            <pubDate>Wed, 09 Aug 2023 16:34:51 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev-hyewon/post/2353b606-623e-47f8-9db6-e0e3e02b3e55/image.png" alt=""></p>
<h3 id="이슈">이슈</h3>
<p>Switch문에 대해 컴파일 에러 발생</p>
<h3 id="원인">원인</h3>
<p><strong>ESLint와 Prettier 충돌</strong>
prettier 기본 설정 의해 swith문에서 case에 대해 들여쓰기가 적용되었는데,
최근 eslint에 추가한 indent 규칙은 switch와 case가 동일 선상에 있는 것을 기본으로 합니다.</p>
<pre><code class="language-json">&quot;rules&quot;: {
  &quot;indent&quot;: [&quot;error&quot;, 2],
  //...
}</code></pre>
<h3 id="해결">해결</h3>
<p><strong>SwitchCase 옵션 <code>{ "SwitchCase": 1 }</code> 을 추가하기</strong>
case절 에 대한 들여쓰기 수준을 설정하는 옵션으로 default가 <code>{ "SwitchCase": 0 }</code> 입니다.</p>
<pre><code class="language-json">&quot;rules&quot;: {
  &quot;indent&quot;: [&quot;error&quot;, 2, { &quot;SwitchCase&quot;: 1 }],
  //...
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[잘못된 Author로 Push한 commit 수정하기]]></title>
            <link>https://velog.io/@dev-hyewon/%EC%9E%98%EB%AA%BB%EB%90%9C-Author%EB%A1%9C-Push%ED%95%9C-commit-%EC%88%98%EC%A0%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dev-hyewon/%EC%9E%98%EB%AA%BB%EB%90%9C-Author%EB%A1%9C-Push%ED%95%9C-commit-%EC%88%98%EC%A0%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 06 Aug 2023 09:14:11 GMT</pubDate>
            <description><![CDATA[<h2 id="잘못된-git-config-수정하기">잘못된 git config 수정하기</h2>
<h3 id="이슈">이슈</h3>
<p>어느날 github에 가보니 그동안 올린 커밋으로 잔디가 안심겨 있는 현상을 발견했습니다.
레포지토리만 볼 때는 잘 올라가는 것 같았는데 왜 이러나 하다가</p>
<pre><code class="language-Bash">$ git log
commit 9417858b9d96e3ec80def9452619ac48bfaedc90 (HEAD -&gt; frontend, origin/frontend, origin/HEAD)
Author: dev-hyewon &lt;developer.hyewon@gamil.com&gt;
Date:   Sun Aug 6 13:56:59 2023 +0900

    modify tech stack style</code></pre>
<p> 터미널로 로그를 확인하던 중 계정 이메일에 오타를 발견했습니다.
 그렇습니다. gmail이 아니라 gamil로 설정되어 본래 계정과 불일치했던거죠...</p>
<p> github의 잔디도 안심어져 있는 걸 보니 며칠 전부터 이 상태였어요.
 그동안 git push와 git pull 모두 정상 동작해서 눈치채지 못했네요.</p>
<h3 id="원인">원인</h3>
<pre><code class="language-bash"> $ git config --list | grep &#39;^user\.&#39;
 user.email=developer.hyewon@gamil.com
 user.name=dev-hyewon</code></pre>
<p> <code>git config --list</code> 명령어로 사용자 정보를 확인해봅니다.
 잘못 설정된 git config가 보입니다... (흑흑)</p>
<h3 id="해결">해결</h3>
<pre><code class="language-bash"> $ git config --global user.email &quot;developer.hyewon@gmail.com&quot;</code></pre>
<p> <code>git config --global user.email "$email"</code> 명령어로 이메일을 수정합니다.
 지금부터 만들어지는 커밋은 수정한 계정으로 저장될 겁니다.
 문제는 이미 올라간 커밋들이 있는데, 무시할 수는 없다는 거죠.
 이미 올라간 커밋도 수정해보겠습니다.</p>
<p> <br/><br/></p>
<h2 id="이미-push한-커밋-수정하기">이미 push한 커밋 수정하기</h2>
<h3 id="1-수정할-커밋-고르기">1. 수정할 커밋 고르기</h3>
<pre><code class="language-bash"> # 0. 로그를 확인해서 author 정보가 잘못된 커밋들을 확인합니다.
 $ git log

 # 1. 수정할 커밋 선정하기. 
 $ git rebase -i --root</code></pre>
<p> <img src="https://velog.velcdn.com/images/dev-hyewon/post/30d1aa08-1469-41f3-978b-48fed6e2f24b/image.png" alt="">
 <code>git rebase -i --root</code> 명령어에 의해 root에서 부터 HEAD까지의 커밋들이 보입니다.
 각 커밋 아이디(해쉬) 앞에 <code>pick</code> 명령어가 있는데, 이 중 수정할 커밋들만 <code>e</code> 명령어로 수정합니다.
 마무리로 <code>Esc</code> 버튼을 눌러 vi 명령 모드로 변경하고, <code>:wq</code>를 입력해서 vi 종료하고 나옵니다.</p>
<pre><code class="language-bash">Stopped at 05d2bdf...  Initialize project using Create React App
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue</code></pre>
<p>vi가 종료되면 터미널에 위와 같은 Stopped at ~ 라는 메세지가 표시됩니다.
<img src="https://velog.velcdn.com/images/dev-hyewon/post/a612f89e-3081-4670-9652-311b476d6870/image.png" alt=""></p>
<p>Shell 프롬프트에 표시되어 있던 브랜치에 REBASE N/M 문구가 생긴 것을 확인하면,
수정할 준비가 다 되었습니다.</p>
<h3 id="2-commit-author-수정하기">2. commit author 수정하기</h3>
<pre><code class="language-bash"> # 2-1. author 정보 수정하기
 $ git commit --amend --author=&quot;dev-hyewon &lt;developer.hyewon@gmail.com&gt;&quot;

 # 2-2. author 정보 git config 값으로 수정하기
 $ git commit --amend --author=&quot;$(git config user.name) &lt;$(git config user.email)&gt;&quot;

 # 2-3. git config 값 변수 처리 후 author 정보 변수 값으로 수정하기
 $ name=$(git config user.name)
 $ email=$(git config user.email)
 $ git commit --amend --author=&quot;$name &lt;$email&gt;&quot;</code></pre>
<p><code>git commit --amend --author="$name <$email>"</code> 명령어로 커밋 author를 수정합니다.
2-1번처럼 이메일을 다시 타자칠 자신이 없다면 2-2나 2-3으로 입력합니다.
  명령어 입력 시 commitMessage에 대한 vi가 열리는 데 <code>:wq</code>를 입력해서 vi 종료 시킵니다.</p>
<h3 id="3-다음-커밋으로-넘어가기">3. 다음 커밋으로 넘어가기</h3>
<pre><code class="language-bash"># 3. 다음 커밋으로 넘어가기
$ git rebase --continue</code></pre>
<p><img src="https://velog.velcdn.com/images/dev-hyewon/post/b9a2e0f2-782a-47fc-b057-4aff9ac30a51/image.png" alt="">
<code>git rebase --continue</code> 시 다음 커밋으로 넘어가서 REBASE N/M의 N 숫자가 변경된 것을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/dev-hyewon/post/4ff74737-96c3-42f1-bf2e-a47824bd40fc/image.png" alt="">
만약 다음 커밋이 e명령어로 변경하지 않았던 커밋일 경우
e명령어를 사용한 커밋에 도달할 때까지 건너뜁니다.</p>
<p><img src="https://velog.velcdn.com/images/dev-hyewon/post/bc3368c8-68fb-41fd-8a6a-d5386b5e482a/image.png" alt="">
위 이미지처럼 stopped 가 아닌 Successfully rebased 라는 메시지가 나오면
모든 커밋이 수정 완료된 것입니다.</p>
<p>모든 커밋이 수정될 때까지 <code>git commit --amend --author="$name <$email>"</code> 명령어와
<code>git rebase --continue</code> 명령어를 반복하면 됩니다.</p>
<h3 id="4-변경-사항-github에-반영하기">4. 변경 사항 Github에 반영하기</h3>
<pre><code class="language-bash">#4. 저장소에 강제로 반영하기
$ git push -f origin HEAD</code></pre>
<p>  <code>git push -f origin HEAD</code> 명령어로 Github에 변경사항이 반영됩니다.</p>
<p>참고로 모든 커밋 수정 완료되기 전에 push해도 되지만 그럴 경우
HEAD 대신 브랜치 명으로 push해야해요.</p>
<p><img src="https://velog.velcdn.com/images/dev-hyewon/post/0d7bd847-d67d-4e0b-bb9e-fd64e6e33319/image.png" alt="">
Github에 이번주 동안 작업 했던 커밋의 잔디가 안심어졌었는데,
잔디가 파릇파릇하게 돋아났어요. 만족!</p>
]]></description>
        </item>
    </channel>
</rss>